From c73a39f79764afb5fb1983986c4360b64334dbfc Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 4 Mar 2026 15:44:27 -0800 Subject: [PATCH 01/50] Allow JIT based on site or resource --- server/private/routers/ssh/signSshKey.ts | 1 - .../routers/olm/handleOlmRegisterMessage.ts | 14 +- server/routers/olm/handleOlmRelayMessage.ts | 2 +- .../handleOlmServerInitAddPeerHandshake.ts | 142 ++++++++++++++++++ server/routers/olm/handleOlmUnRelayMessage.ts | 2 +- server/routers/olm/index.ts | 1 + server/routers/ws/messageHandlers.ts | 4 +- 7 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 server/routers/olm/handleOlmServerInitAddPeerHandshake.ts diff --git a/server/private/routers/ssh/signSshKey.ts b/server/private/routers/ssh/signSshKey.ts index 0e4c4e9ef..d6fe88eb8 100644 --- a/server/private/routers/ssh/signSshKey.ts +++ b/server/private/routers/ssh/signSshKey.ts @@ -29,7 +29,6 @@ import HttpCode from "@server/types/HttpCode"; import createHttpError from "http-errors"; import logger from "@server/logger"; import { fromError } from "zod-validation-error"; -import { OpenAPITags, registry } from "@server/openApi"; import { eq, or, and } from "drizzle-orm"; import { canUserAccessSiteResource } from "@server/auth/canUserAccessSiteResource"; import { signPublicKey, getOrgCAKeys } from "@server/lib/sshCA"; diff --git a/server/routers/olm/handleOlmRegisterMessage.ts b/server/routers/olm/handleOlmRegisterMessage.ts index 7fa43c9cb..90ba3b813 100644 --- a/server/routers/olm/handleOlmRegisterMessage.ts +++ b/server/routers/olm/handleOlmRegisterMessage.ts @@ -265,12 +265,14 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { return; } - // NOTE: its important that the client here is the old client and the public key is the new key - const siteConfigurations = await buildSiteConfigurationForOlmClient( - client, - publicKey, - relay - ); + // // NOTE: its important that the client here is the old client and the public key is the new key + // const siteConfigurations = await buildSiteConfigurationForOlmClient( + // client, + // publicKey, + // relay + // ); + + const siteConfigurations: any = []; // REMOVED THIS SO IT CREATES THE INTERFACE AND JUST WAITS FOR THE SITES // if (siteConfigurations.length === 0) { diff --git a/server/routers/olm/handleOlmRelayMessage.ts b/server/routers/olm/handleOlmRelayMessage.ts index 88886cd15..a681dc558 100644 --- a/server/routers/olm/handleOlmRelayMessage.ts +++ b/server/routers/olm/handleOlmRelayMessage.ts @@ -18,7 +18,7 @@ export const handleOlmRelayMessage: MessageHandler = async (context) => { } if (!olm.clientId) { - logger.warn("Olm has no site!"); // TODO: Maybe we create the site here? + logger.warn("Olm has no client!"); return; } diff --git a/server/routers/olm/handleOlmServerInitAddPeerHandshake.ts b/server/routers/olm/handleOlmServerInitAddPeerHandshake.ts new file mode 100644 index 000000000..35e47cc15 --- /dev/null +++ b/server/routers/olm/handleOlmServerInitAddPeerHandshake.ts @@ -0,0 +1,142 @@ +import { + db, + exitNodes, + Site, + siteResources +} from "@server/db"; +import { MessageHandler } from "@server/routers/ws"; +import { clients, Olm, sites } from "@server/db"; +import { and, eq, or } from "drizzle-orm"; +import logger from "@server/logger"; +import { initPeerAddHandshake } from "./peers"; + +export const handleOlmServerInitAddPeerHandshake: MessageHandler = async ( + context +) => { + logger.info("Handling register olm message!"); + const { message, client: c, sendToClient } = context; + const olm = c as Olm; + + if (!olm) { + logger.warn("Olm not found"); + return; + } + + if (!olm.clientId) { + logger.warn("Olm has no client!"); // TODO: Maybe we create the site here? + return; + } + + const clientId = olm.clientId; + + const [client] = await db + .select() + .from(clients) + .where(eq(clients.clientId, clientId)) + .limit(1); + + if (!client) { + logger.warn("Client not found"); + return; + } + + const { siteId, resourceId } = message.data; + + let site: Site | null = null; + if (siteId) { + // get the site + const [siteRes] = await db + .select() + .from(sites) + .where(eq(sites.siteId, siteId)) + .limit(1); + if (siteRes) { + site = siteRes; + } + } + + if (resourceId && !site) { + const resources = await db + .select() + .from(siteResources) + .where( + and( + or( + eq(siteResources.niceId, resourceId), + eq(siteResources.alias, resourceId) + ), + eq(siteResources.orgId, client.orgId) + ) + ); + + if (!resources || resources.length === 0) { + logger.error(`handleOlmServerPeerAddMessage: Resource not found`); + return; + } + + if (resources.length > 1) { + // error but this should not happen because the nice id cant contain a dot and the alias has to have a dot and both have to be unique within the org so there should never be multiple matches + logger.error( + `handleOlmServerPeerAddMessage: Multiple resources found matching the criteria` + ); + return; + } + const siteIdFromResource = resources[0].siteId; + + // get the site + const [siteRes] = await db + .select() + .from(sites) + .where(eq(sites.siteId, siteIdFromResource)); + if (!siteRes) { + logger.error( + `handleOlmServerPeerAddMessage: Site with ID ${site} not found` + ); + return; + } + + site = siteRes; + } + + if (!site) { + logger.error(`handleOlmServerPeerAddMessage: Site not found`); + return; + } + + if (!site.exitNodeId) { + logger.error( + `handleOlmServerPeerAddMessage: Site with ID ${site.siteId} has no exit node` + ); + return; + } + + // get the exit node from the side + const [exitNode] = await db + .select() + .from(exitNodes) + .where(eq(exitNodes.exitNodeId, site.exitNodeId)); + + if (!exitNode) { + logger.error( + `handleOlmServerPeerAddMessage: Site with ID ${site.siteId} has no exit node` + ); + return; + } + + // also trigger the peer add handshake in case the peer was not already added to the olm and we need to hole punch + // if it has already been added this will be a no-op + await initPeerAddHandshake( + // this will kick off the add peer process for the client + client.clientId, + { + siteId: site.siteId, + exitNode: { + publicKey: exitNode.publicKey, + endpoint: exitNode.endpoint + } + }, + olm.olmId + ); + + return; +}; diff --git a/server/routers/olm/handleOlmUnRelayMessage.ts b/server/routers/olm/handleOlmUnRelayMessage.ts index 5f47a095e..554c7c100 100644 --- a/server/routers/olm/handleOlmUnRelayMessage.ts +++ b/server/routers/olm/handleOlmUnRelayMessage.ts @@ -17,7 +17,7 @@ export const handleOlmUnRelayMessage: MessageHandler = async (context) => { } if (!olm.clientId) { - logger.warn("Olm has no site!"); // TODO: Maybe we create the site here? + logger.warn("Olm has no client!"); return; } diff --git a/server/routers/olm/index.ts b/server/routers/olm/index.ts index f04ba0bee..322428572 100644 --- a/server/routers/olm/index.ts +++ b/server/routers/olm/index.ts @@ -11,3 +11,4 @@ export * from "./handleOlmServerPeerAddMessage"; export * from "./handleOlmUnRelayMessage"; export * from "./recoverOlmWithFingerprint"; export * from "./handleOlmDisconnectingMessage"; +export * from "./handleOlmServerInitAddPeerHandshake"; diff --git a/server/routers/ws/messageHandlers.ts b/server/routers/ws/messageHandlers.ts index 9a14344a5..f041c9d56 100644 --- a/server/routers/ws/messageHandlers.ts +++ b/server/routers/ws/messageHandlers.ts @@ -15,7 +15,8 @@ import { startOlmOfflineChecker, handleOlmServerPeerAddMessage, handleOlmUnRelayMessage, - handleOlmDisconnecingMessage + handleOlmDisconnecingMessage, + handleOlmServerInitAddPeerHandshake } from "../olm"; import { handleHealthcheckStatusMessage } from "../target"; import { handleRoundTripMessage } from "./handleRoundTripMessage"; @@ -23,6 +24,7 @@ import { MessageHandler } from "./types"; export const messageHandlers: Record = { "olm/wg/server/peer/add": handleOlmServerPeerAddMessage, + "olm/wg/server/peer/init": handleOlmServerInitAddPeerHandshake, "olm/wg/register": handleOlmRegisterMessage, "olm/wg/relay": handleOlmRelayMessage, "olm/wg/unrelay": handleOlmUnRelayMessage, From 1bfff630bf9aa3365543200c57499221db11dc86 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 4 Mar 2026 17:46:58 -0800 Subject: [PATCH 02/50] Jit working for sites --- server/private/routers/ws/ws.ts | 2 +- .../handleOlmServerInitAddPeerHandshake.ts | 105 +++++++++++++++++- .../olm/handleOlmServerPeerAddMessage.ts | 5 +- server/routers/olm/peers.ts | 6 +- 4 files changed, 110 insertions(+), 8 deletions(-) diff --git a/server/private/routers/ws/ws.ts b/server/private/routers/ws/ws.ts index 342dba58c..7d1769bca 100644 --- a/server/private/routers/ws/ws.ts +++ b/server/private/routers/ws/ws.ts @@ -76,7 +76,7 @@ const processMessage = async ( clientId, message.type, // Pass message type for granular limiting 100, // max requests per window - 20, // max requests per message type per window + 100, // max requests per message type per window 60 * 1000 // window in milliseconds ); if (rateLimitResult.isLimited) { diff --git a/server/routers/olm/handleOlmServerInitAddPeerHandshake.ts b/server/routers/olm/handleOlmServerInitAddPeerHandshake.ts index 35e47cc15..54badb2dc 100644 --- a/server/routers/olm/handleOlmServerInitAddPeerHandshake.ts +++ b/server/routers/olm/handleOlmServerInitAddPeerHandshake.ts @@ -1,4 +1,6 @@ import { + clientSiteResourcesAssociationsCache, + clientSitesAssociationsCache, db, exitNodes, Site, @@ -40,7 +42,7 @@ export const handleOlmServerInitAddPeerHandshake: MessageHandler = async ( return; } - const { siteId, resourceId } = message.data; + const { siteId, resourceId, chainId } = message.data; let site: Site | null = null; if (siteId) { @@ -71,6 +73,19 @@ export const handleOlmServerInitAddPeerHandshake: MessageHandler = async ( if (!resources || resources.length === 0) { logger.error(`handleOlmServerPeerAddMessage: Resource not found`); + // cancel the request from the olm side to not keep doing this + await sendToClient( + olm.olmId, + { + type: "olm/wg/peer/chain/cancel", + data: { + chainId + } + }, + { incrementConfigVersion: false } + ).catch((error) => { + logger.warn(`Error sending message:`, error); + }); return; } @@ -81,7 +96,46 @@ export const handleOlmServerInitAddPeerHandshake: MessageHandler = async ( ); return; } - const siteIdFromResource = resources[0].siteId; + + const resource = resources[0]; + + const currentResourceAssociationCaches = await db + .select() + .from(clientSiteResourcesAssociationsCache) + .where( + and( + eq( + clientSiteResourcesAssociationsCache.siteResourceId, + resource.siteResourceId + ), + eq( + clientSiteResourcesAssociationsCache.clientId, + client.clientId + ) + ) + ); + + if (currentResourceAssociationCaches.length === 0) { + logger.error( + `handleOlmServerPeerAddMessage: Client ${client.clientId} does not have access to resource ${resource.siteResourceId}` + ); + // cancel the request from the olm side to not keep doing this + await sendToClient( + olm.olmId, + { + type: "olm/wg/peer/chain/cancel", + data: { + chainId + } + }, + { incrementConfigVersion: false } + ).catch((error) => { + logger.warn(`Error sending message:`, error); + }); + return; + } + + const siteIdFromResource = resource.siteId; // get the site const [siteRes] = await db @@ -103,10 +157,54 @@ export const handleOlmServerInitAddPeerHandshake: MessageHandler = async ( return; } + // check if the client can access this site using the cache + const currentSiteAssociationCaches = await db + .select() + .from(clientSitesAssociationsCache) + .where( + and( + eq(clientSitesAssociationsCache.clientId, client.clientId), + eq(clientSitesAssociationsCache.siteId, site.siteId) + ) + ); + + if (currentSiteAssociationCaches.length === 0) { + logger.error( + `handleOlmServerPeerAddMessage: Client ${client.clientId} does not have access to site ${site.siteId}` + ); + // cancel the request from the olm side to not keep doing this + await sendToClient( + olm.olmId, + { + type: "olm/wg/peer/chain/cancel", + data: { + chainId + } + }, + { incrementConfigVersion: false } + ).catch((error) => { + logger.warn(`Error sending message:`, error); + }); + return; + } + if (!site.exitNodeId) { logger.error( `handleOlmServerPeerAddMessage: Site with ID ${site.siteId} has no exit node` ); + // cancel the request from the olm side to not keep doing this + await sendToClient( + olm.olmId, + { + type: "olm/wg/peer/chain/cancel", + data: { + chainId + } + }, + { incrementConfigVersion: false } + ).catch((error) => { + logger.warn(`Error sending message:`, error); + }); return; } @@ -135,7 +233,8 @@ export const handleOlmServerInitAddPeerHandshake: MessageHandler = async ( endpoint: exitNode.endpoint } }, - olm.olmId + olm.olmId, + chainId ); return; diff --git a/server/routers/olm/handleOlmServerPeerAddMessage.ts b/server/routers/olm/handleOlmServerPeerAddMessage.ts index 53f3474ce..64284f493 100644 --- a/server/routers/olm/handleOlmServerPeerAddMessage.ts +++ b/server/routers/olm/handleOlmServerPeerAddMessage.ts @@ -54,7 +54,7 @@ export const handleOlmServerPeerAddMessage: MessageHandler = async ( return; } - const { siteId } = message.data; + const { siteId, chainId } = message.data; // get the site const [site] = await db @@ -179,7 +179,8 @@ export const handleOlmServerPeerAddMessage: MessageHandler = async ( ), aliases: generateAliasConfig( allSiteResources.map(({ siteResources }) => siteResources) - ) + ), + chainId: chainId, } }, broadcast: false, diff --git a/server/routers/olm/peers.ts b/server/routers/olm/peers.ts index 4ffeff736..66453008e 100644 --- a/server/routers/olm/peers.ts +++ b/server/routers/olm/peers.ts @@ -149,7 +149,8 @@ export async function initPeerAddHandshake( endpoint: string; }; }, - olmId?: string + olmId?: string, + chainId?: string, ) { if (!olmId) { const [olm] = await db @@ -173,7 +174,8 @@ export async function initPeerAddHandshake( publicKey: peer.exitNode.publicKey, relayPort: config.getRawConfig().gerbil.clients_start_port, endpoint: peer.exitNode.endpoint - } + }, + chainId, } }, { incrementConfigVersion: true } From 2a5c9465e90b4abeae05608890ca143ae2594763 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 4 Mar 2026 22:17:58 -0800 Subject: [PATCH 03/50] Add chainId field passthrough --- server/routers/olm/handleOlmRelayMessage.ts | 5 +++-- server/routers/olm/handleOlmUnRelayMessage.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/server/routers/olm/handleOlmRelayMessage.ts b/server/routers/olm/handleOlmRelayMessage.ts index a681dc558..7196824d2 100644 --- a/server/routers/olm/handleOlmRelayMessage.ts +++ b/server/routers/olm/handleOlmRelayMessage.ts @@ -41,7 +41,7 @@ export const handleOlmRelayMessage: MessageHandler = async (context) => { return; } - const { siteId } = message.data; + const { siteId, chainId } = message.data; // Get the site const [site] = await db @@ -90,7 +90,8 @@ export const handleOlmRelayMessage: MessageHandler = async (context) => { data: { siteId: siteId, relayEndpoint: exitNode.endpoint, - relayPort: config.getRawConfig().gerbil.clients_start_port + relayPort: config.getRawConfig().gerbil.clients_start_port, + chainId } }, broadcast: false, diff --git a/server/routers/olm/handleOlmUnRelayMessage.ts b/server/routers/olm/handleOlmUnRelayMessage.ts index 554c7c100..a7b426023 100644 --- a/server/routers/olm/handleOlmUnRelayMessage.ts +++ b/server/routers/olm/handleOlmUnRelayMessage.ts @@ -40,7 +40,7 @@ export const handleOlmUnRelayMessage: MessageHandler = async (context) => { return; } - const { siteId } = message.data; + const { siteId, chainId } = message.data; // Get the site const [site] = await db @@ -87,7 +87,8 @@ export const handleOlmUnRelayMessage: MessageHandler = async (context) => { type: "olm/wg/peer/unrelay", data: { siteId: siteId, - endpoint: site.endpoint + endpoint: site.endpoint, + chainId } }, broadcast: false, From 1a2069a6d92f5bb5a03008966893ef3d4405c4b7 Mon Sep 17 00:00:00 2001 From: Fizza-Mukhtar Date: Thu, 5 Mar 2026 00:39:03 -0800 Subject: [PATCH 04/50] fix: prevent resource creation with dashboard domain to avoid redirect loop --- server/routers/resource/createResource.ts | 14 ++++++++++++++ server/routers/resource/updateResource.ts | 14 ++++++++++++++ .../settings/resources/proxy/create/page.tsx | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/server/routers/resource/createResource.ts b/server/routers/resource/createResource.ts index 6c88c5797..384bb8b53 100644 --- a/server/routers/resource/createResource.ts +++ b/server/routers/resource/createResource.ts @@ -223,6 +223,20 @@ async function createHttpResource( ); } + // Prevent creating resource with same domain as dashboard + const dashboardUrl = process.env.DASHBOARD_URL; + if (dashboardUrl) { + const dashboardHost = new URL(dashboardUrl).hostname; + if (fullDomain === dashboardHost) { + return next( + createHttpError( + HttpCode.CONFLICT, + "Resource domain cannot be the same as the dashboard domain" + ) + ); + } + } + if (build != "oss") { const existingLoginPages = await db .select() diff --git a/server/routers/resource/updateResource.ts b/server/routers/resource/updateResource.ts index 42e2849f6..becad5d2c 100644 --- a/server/routers/resource/updateResource.ts +++ b/server/routers/resource/updateResource.ts @@ -353,6 +353,20 @@ async function updateHttpResource( ); } + // Prevent updating resource with same domain as dashboard + const dashboardUrl = process.env.DASHBOARD_URL; + if (dashboardUrl) { + const dashboardHost = new URL(dashboardUrl).hostname; + if (fullDomain === dashboardHost) { + return next( + createHttpError( + HttpCode.CONFLICT, + "Resource domain cannot be the same as the dashboard domain" + ) + ); + } + } + if (build != "oss") { const existingLoginPages = await db .select() diff --git a/src/app/[orgId]/settings/resources/proxy/create/page.tsx b/src/app/[orgId]/settings/resources/proxy/create/page.tsx index ff51a311b..127917555 100644 --- a/src/app/[orgId]/settings/resources/proxy/create/page.tsx +++ b/src/app/[orgId]/settings/resources/proxy/create/page.tsx @@ -559,7 +559,7 @@ export default function Page() { toast({ variant: "destructive", title: t("resourceErrorCreate"), - description: t("resourceErrorCreateMessageDescription") + description: formatAxiosError(e, t("resourceErrorCreateMessageDescription")) }); } From 4cfcc64481f0b6c0c2f880ac41899661aa54a8b0 Mon Sep 17 00:00:00 2001 From: Fizza-Mukhtar Date: Thu, 5 Mar 2026 01:07:30 -0800 Subject: [PATCH 05/50] fix: use config instead of process.env for dashboard URL check --- server/routers/resource/createResource.ts | 2 +- server/routers/resource/updateResource.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/routers/resource/createResource.ts b/server/routers/resource/createResource.ts index 384bb8b53..e07880ac2 100644 --- a/server/routers/resource/createResource.ts +++ b/server/routers/resource/createResource.ts @@ -224,7 +224,7 @@ async function createHttpResource( } // Prevent creating resource with same domain as dashboard - const dashboardUrl = process.env.DASHBOARD_URL; + const dashboardUrl = config.getRawConfig().app.dashboard_url; if (dashboardUrl) { const dashboardHost = new URL(dashboardUrl).hostname; if (fullDomain === dashboardHost) { diff --git a/server/routers/resource/updateResource.ts b/server/routers/resource/updateResource.ts index becad5d2c..01f3e79ff 100644 --- a/server/routers/resource/updateResource.ts +++ b/server/routers/resource/updateResource.ts @@ -354,7 +354,7 @@ async function updateHttpResource( } // Prevent updating resource with same domain as dashboard - const dashboardUrl = process.env.DASHBOARD_URL; + const dashboardUrl = config.getRawConfig().app.dashboard_url; if (dashboardUrl) { const dashboardHost = new URL(dashboardUrl).hostname; if (fullDomain === dashboardHost) { From cebcf3e33787043326c5116b4df11ba60527e841 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:40:41 +0000 Subject: [PATCH 06/50] Bump express-rate-limit from 8.2.1 to 8.2.2 Bumps [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) from 8.2.1 to 8.2.2. - [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases) - [Commits](https://github.com/express-rate-limit/express-rate-limit/compare/v8.2.1...v8.2.2) --- updated-dependencies: - dependency-name: express-rate-limit dependency-version: 8.2.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06dccc8bf..1e946c3ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.1", + "express-rate-limit": "8.2.2", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", @@ -14392,12 +14392,12 @@ } }, "node_modules/express-rate-limit": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz", - "integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.2.tgz", + "integrity": "sha512-Ybv7bqtOgA914MLwaHWVFXMpMYeR1MQu/D+z2MaLYteqBsTIp9sY3AU7mGNLMJv8eLg8uQMpE20I+L2Lv49nSg==", "license": "MIT", "dependencies": { - "ip-address": "10.0.1" + "ip-address": "10.1.0" }, "engines": { "node": ">= 16" @@ -15490,9 +15490,9 @@ } }, "node_modules/ip-address": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", - "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "license": "MIT", "engines": { "node": ">= 12" diff --git a/package.json b/package.json index 625853042..df92d1a64 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.1", + "express-rate-limit": "8.2.2", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", From 9405b0b70a6e06dbe679f847f10a95b61f458b11 Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 6 Mar 2026 14:09:57 -0800 Subject: [PATCH 07/50] Force jit above site limit --- .../routers/olm/handleOlmRegisterMessage.ts | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/server/routers/olm/handleOlmRegisterMessage.ts b/server/routers/olm/handleOlmRegisterMessage.ts index 90ba3b813..1e209d13e 100644 --- a/server/routers/olm/handleOlmRegisterMessage.ts +++ b/server/routers/olm/handleOlmRegisterMessage.ts @@ -17,6 +17,8 @@ import { getUserDeviceName } from "@server/db/names"; import { buildSiteConfigurationForOlmClient } from "./buildConfiguration"; import { OlmErrorCodes, sendOlmError } from "./error"; import { handleFingerprintInsertion } from "./fingerprintingUtils"; +import { Alias } from "@server/lib/ip"; +import { build } from "@server/build"; export const handleOlmRegisterMessage: MessageHandler = async (context) => { logger.info("Handling register olm message!"); @@ -265,20 +267,26 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { return; } - // // NOTE: its important that the client here is the old client and the public key is the new key - // const siteConfigurations = await buildSiteConfigurationForOlmClient( - // client, - // publicKey, - // relay - // ); + let siteConfigurations: { + siteId: number; + name: string; + endpoint: string; + publicKey: string | null; + serverIP: string | null; + serverPort: number | null; + remoteSubnets: string[]; + aliases: Alias[]; + }[] = []; - const siteConfigurations: any = []; - - // REMOVED THIS SO IT CREATES THE INTERFACE AND JUST WAITS FOR THE SITES - // if (siteConfigurations.length === 0) { - // logger.warn("No valid site configurations found"); - // return; - // } + // If we have too many sites we need to drop into fully JIT mode by not sending any of the sites + if (sitesCount <= 250 && build == "saas") { // THIS IS THE MAX ON THE BUSINESS TIER + // NOTE: its important that the client here is the old client and the public key is the new key + siteConfigurations = await buildSiteConfigurationForOlmClient( + client, + publicKey, + relay + ); + } // Return connect message with all site configurations return { From 14d6ff25a717e995ddf20d21a19c045324117788 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 22:14:56 +0000 Subject: [PATCH 08/50] Bump fast-xml-parser and @aws-sdk/xml-builder Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) and [@aws-sdk/xml-builder](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/xml-builder). These dependencies needed to be updated together. Updates `fast-xml-parser` from 5.3.6 to 5.4.1 - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.6...v5.4.1) Updates `@aws-sdk/xml-builder` from 3.972.5 to 3.972.10 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/xml-builder/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/xml-builder) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.4.1 dependency-type: indirect - dependency-name: "@aws-sdk/xml-builder" dependency-version: 3.972.10 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e946c3ed..3e070b8ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1035,13 +1035,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.5.tgz", - "integrity": "sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA==", + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.10.tgz", + "integrity": "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "fast-xml-parser": "5.3.6", + "@smithy/types": "^4.13.0", + "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" }, "engines": { @@ -8463,9 +8463,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", - "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", + "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -14517,10 +14517,22 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/fast-xml-parser": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz", - "integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", "funding": [ { "type": "github", @@ -14529,6 +14541,7 @@ ], "license": "MIT", "dependencies": { + "fast-xml-builder": "^1.0.0", "strnum": "^2.1.2" }, "bin": { @@ -20574,9 +20587,9 @@ } }, "node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz", + "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==", "funding": [ { "type": "github", From 0503c6e66e12c6a7ed343600960c205cc3b82311 Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 6 Mar 2026 15:47:41 -0800 Subject: [PATCH 09/50] Handle JIT for ssh --- server/db/pg/schema/schema.ts | 1 + server/db/sqlite/schema/schema.ts | 3 + server/private/routers/ssh/signSshKey.ts | 2 + server/routers/newt/buildConfiguration.ts | 79 +++++++++++-------- .../routers/olm/handleOlmRegisterMessage.ts | 49 +++++++----- server/routers/olm/peers.ts | 19 ++++- 6 files changed, 96 insertions(+), 57 deletions(-) diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index 504ea761f..63bb05358 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -720,6 +720,7 @@ export const clientSitesAssociationsCache = pgTable( .notNull(), siteId: integer("siteId").notNull(), isRelayed: boolean("isRelayed").notNull().default(false), + isJitMode: boolean("isJitMode").notNull().default(false), endpoint: varchar("endpoint"), publicKey: varchar("publicKey") // this will act as the session's public key for hole punching so we can track when it changes } diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index 2bd11ee0c..6183dfd79 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -409,6 +409,9 @@ export const clientSitesAssociationsCache = sqliteTable( isRelayed: integer("isRelayed", { mode: "boolean" }) .notNull() .default(false), + isJitMode: integer("isJitMode", { mode: "boolean" }) + .notNull() + .default(false), endpoint: text("endpoint"), publicKey: text("publicKey") // this will act as the session's public key for hole punching so we can track when it changes } diff --git a/server/private/routers/ssh/signSshKey.ts b/server/private/routers/ssh/signSshKey.ts index d6fe88eb8..e70951812 100644 --- a/server/private/routers/ssh/signSshKey.ts +++ b/server/private/routers/ssh/signSshKey.ts @@ -63,6 +63,7 @@ export type SignSshKeyResponse = { sshUsername: string; sshHost: string; resourceId: number; + siteId: number; keyId: string; validPrincipals: string[]; validAfter: string; @@ -452,6 +453,7 @@ export async function signSshKey( sshUsername: usernameToUse, sshHost: sshHost, resourceId: resource.siteResourceId, + siteId: resource.siteId, keyId: cert.keyId, validPrincipals: cert.validPrincipals, validAfter: cert.validAfter.toISOString(), diff --git a/server/routers/newt/buildConfiguration.ts b/server/routers/newt/buildConfiguration.ts index 65cb18a21..3c55d6b95 100644 --- a/server/routers/newt/buildConfiguration.ts +++ b/server/routers/newt/buildConfiguration.ts @@ -1,4 +1,15 @@ -import { clients, clientSiteResourcesAssociationsCache, clientSitesAssociationsCache, db, ExitNode, resources, Site, siteResources, targetHealthCheck, targets } from "@server/db"; +import { + clients, + clientSiteResourcesAssociationsCache, + clientSitesAssociationsCache, + db, + ExitNode, + resources, + Site, + siteResources, + targetHealthCheck, + targets +} from "@server/db"; import logger from "@server/logger"; import { initPeerAddHandshake, updatePeer } from "../olm/peers"; import { eq, and } from "drizzle-orm"; @@ -69,40 +80,42 @@ export async function buildClientConfigurationForNewtClient( // ) // ); - // update the peer info on the olm - // if the peer has not been added yet this will be a no-op - await updatePeer(client.clients.clientId, { - siteId: site.siteId, - endpoint: site.endpoint!, - relayEndpoint: `${exitNode.endpoint}:${config.getRawConfig().gerbil.clients_start_port}`, - publicKey: site.publicKey!, - serverIP: site.address, - serverPort: site.listenPort - // remoteSubnets: generateRemoteSubnets( - // allSiteResources.map( - // ({ siteResources }) => siteResources - // ) - // ), - // aliases: generateAliasConfig( - // allSiteResources.map( - // ({ siteResources }) => siteResources - // ) - // ) - }); + if (!client.clientSitesAssociationsCache.isJitMode) { // if we are adding sites through jit then dont add the site to the olm + // update the peer info on the olm + // if the peer has not been added yet this will be a no-op + await updatePeer(client.clients.clientId, { + siteId: site.siteId, + endpoint: site.endpoint!, + relayEndpoint: `${exitNode.endpoint}:${config.getRawConfig().gerbil.clients_start_port}`, + publicKey: site.publicKey!, + serverIP: site.address, + serverPort: site.listenPort + // remoteSubnets: generateRemoteSubnets( + // allSiteResources.map( + // ({ siteResources }) => siteResources + // ) + // ), + // aliases: generateAliasConfig( + // allSiteResources.map( + // ({ siteResources }) => siteResources + // ) + // ) + }); - // also trigger the peer add handshake in case the peer was not already added to the olm and we need to hole punch - // if it has already been added this will be a no-op - await initPeerAddHandshake( - // this will kick off the add peer process for the client - client.clients.clientId, - { - siteId, - exitNode: { - publicKey: exitNode.publicKey, - endpoint: exitNode.endpoint + // also trigger the peer add handshake in case the peer was not already added to the olm and we need to hole punch + // if it has already been added this will be a no-op + await initPeerAddHandshake( + // this will kick off the add peer process for the client + client.clients.clientId, + { + siteId, + exitNode: { + publicKey: exitNode.publicKey, + endpoint: exitNode.endpoint + } } - } - ); + ); + } return { publicKey: client.clients.pubKey!, diff --git a/server/routers/olm/handleOlmRegisterMessage.ts b/server/routers/olm/handleOlmRegisterMessage.ts index 1e209d13e..91a2aa138 100644 --- a/server/routers/olm/handleOlmRegisterMessage.ts +++ b/server/routers/olm/handleOlmRegisterMessage.ts @@ -209,6 +209,32 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { } } + // Get all sites data + const sitesCountResult = await db + .select({ count: count() }) + .from(sites) + .innerJoin( + clientSitesAssociationsCache, + eq(sites.siteId, clientSitesAssociationsCache.siteId) + ) + .where(eq(clientSitesAssociationsCache.clientId, client.clientId)); + + // Extract the count value from the result array + const sitesCount = + sitesCountResult.length > 0 ? sitesCountResult[0].count : 0; + + // Prepare an array to store site configurations + logger.debug(`Found ${sitesCount} sites for client ${client.clientId}`); + + let jitMode = false; + if (sitesCount > 250 && build == "saas") { + // THIS IS THE MAX ON THE BUSINESS TIER + // we have too many sites + // If we have too many sites we need to drop into fully JIT mode by not sending any of the sites + logger.info("Too many sites (%d), dropping into JIT mode", sitesCount) + jitMode = true; + } + logger.debug( `Olm client ID: ${client.clientId}, Public Key: ${publicKey}, Relay: ${relay}` ); @@ -235,28 +261,12 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { await db .update(clientSitesAssociationsCache) .set({ - isRelayed: relay == true + isRelayed: relay == true, + isJitMode: jitMode }) .where(eq(clientSitesAssociationsCache.clientId, client.clientId)); } - // Get all sites data - const sitesCountResult = await db - .select({ count: count() }) - .from(sites) - .innerJoin( - clientSitesAssociationsCache, - eq(sites.siteId, clientSitesAssociationsCache.siteId) - ) - .where(eq(clientSitesAssociationsCache.clientId, client.clientId)); - - // Extract the count value from the result array - const sitesCount = - sitesCountResult.length > 0 ? sitesCountResult[0].count : 0; - - // Prepare an array to store site configurations - logger.debug(`Found ${sitesCount} sites for client ${client.clientId}`); - // this prevents us from accepting a register from an olm that has not hole punched yet. // the olm will pump the register so we can keep checking // TODO: I still think there is a better way to do this rather than locking it out here but ??? @@ -278,8 +288,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { aliases: Alias[]; }[] = []; - // If we have too many sites we need to drop into fully JIT mode by not sending any of the sites - if (sitesCount <= 250 && build == "saas") { // THIS IS THE MAX ON THE BUSINESS TIER + if (!jitMode) { // NOTE: its important that the client here is the old client and the public key is the new key siteConfigurations = await buildSiteConfigurationForOlmClient( client, diff --git a/server/routers/olm/peers.ts b/server/routers/olm/peers.ts index 66453008e..06621cac9 100644 --- a/server/routers/olm/peers.ts +++ b/server/routers/olm/peers.ts @@ -1,8 +1,8 @@ import { sendToClient } from "#dynamic/routers/ws"; -import { db, olms } from "@server/db"; +import { clientSitesAssociationsCache, db, olms } from "@server/db"; import config from "@server/lib/config"; import logger from "@server/logger"; -import { eq } from "drizzle-orm"; +import { and, eq } from "drizzle-orm"; import { Alias } from "yaml"; export async function addPeer( @@ -150,7 +150,7 @@ export async function initPeerAddHandshake( }; }, olmId?: string, - chainId?: string, + chainId?: string ) { if (!olmId) { const [olm] = await db @@ -175,7 +175,7 @@ export async function initPeerAddHandshake( relayPort: config.getRawConfig().gerbil.clients_start_port, endpoint: peer.exitNode.endpoint }, - chainId, + chainId } }, { incrementConfigVersion: true } @@ -183,6 +183,17 @@ export async function initPeerAddHandshake( logger.warn(`Error sending message:`, error); }); + // update the clientSiteAssociationsCache to make the isJitMode flag false so that JIT mode is disabled for this site if it restarts or something after the connection + await db + .update(clientSitesAssociationsCache) + .set({ isJitMode: false }) + .where( + and( + eq(clientSitesAssociationsCache.clientId, clientId), + eq(clientSitesAssociationsCache.siteId, peer.siteId) + ) + ); + logger.info( `Initiated peer add handshake for site ${peer.siteId} to olm ${olmId}` ); From cf5fb8dc336a93332a649287fe12ac2277793a1d Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 16:36:13 -0700 Subject: [PATCH 10/50] Working on jit --- server/lib/telemetry.ts | 12 +-- server/routers/olm/buildConfiguration.ts | 90 ++++++++++++++----- .../routers/olm/handleOlmRegisterMessage.ts | 30 ++----- 3 files changed, 81 insertions(+), 51 deletions(-) diff --git a/server/lib/telemetry.ts b/server/lib/telemetry.ts index fda59f394..4e957139f 100644 --- a/server/lib/telemetry.ts +++ b/server/lib/telemetry.ts @@ -21,13 +21,13 @@ class TelemetryClient { this.enabled = enabled; const dev = process.env.ENVIRONMENT !== "prod"; - if (dev) { - return; - } + // if (dev) { + // return; + // } - if (build === "saas") { - return; - } + // if (build === "saas") { + // return; + // } if (this.enabled) { this.client = new PostHog( diff --git a/server/routers/olm/buildConfiguration.ts b/server/routers/olm/buildConfiguration.ts index b506366bf..f5ec536ca 100644 --- a/server/routers/olm/buildConfiguration.ts +++ b/server/routers/olm/buildConfiguration.ts @@ -1,5 +1,17 @@ -import { Client, clientSiteResourcesAssociationsCache, clientSitesAssociationsCache, db, exitNodes, siteResources, sites } from "@server/db"; -import { generateAliasConfig, generateRemoteSubnets } from "@server/lib/ip"; +import { + Client, + clientSiteResourcesAssociationsCache, + clientSitesAssociationsCache, + db, + exitNodes, + siteResources, + sites +} from "@server/db"; +import { + Alias, + generateAliasConfig, + generateRemoteSubnets +} from "@server/lib/ip"; import logger from "@server/logger"; import { and, eq } from "drizzle-orm"; import { addPeer, deletePeer } from "../newt/peers"; @@ -8,9 +20,19 @@ import config from "@server/lib/config"; export async function buildSiteConfigurationForOlmClient( client: Client, publicKey: string | null, - relay: boolean + relay: boolean, + jitMode: boolean = false ) { - const siteConfigurations = []; + const siteConfigurations: { + siteId: number; + name: string | null; + endpoint: string | null; + publicKey: string | null; + serverIP: string | null; + serverPort: number | null; + remoteSubnets: string[]; + aliases: Alias[]; + }[] = []; // Get all sites data const sitesData = await db @@ -27,6 +49,46 @@ export async function buildSiteConfigurationForOlmClient( sites: site, clientSitesAssociationsCache: association } of sitesData) { + const allSiteResources = await db // only get the site resources that this client has access to + .select() + .from(siteResources) + .innerJoin( + clientSiteResourcesAssociationsCache, + eq( + siteResources.siteResourceId, + clientSiteResourcesAssociationsCache.siteResourceId + ) + ) + .where( + and( + eq(siteResources.siteId, site.siteId), + eq( + clientSiteResourcesAssociationsCache.clientId, + client.clientId + ) + ) + ); + + if (jitMode) { + // Add site configuration to the array + siteConfigurations.push({ + siteId: site.siteId, + name: null, // this is just to sync the aliases + endpoint: null, + publicKey: null, + serverIP: null, + serverPort: null, + // remoteSubnets: generateRemoteSubnets( + // allSiteResources.map(({ siteResources }) => siteResources) + // ), + remoteSubnets: [], + aliases: generateAliasConfig( + allSiteResources.map(({ siteResources }) => siteResources) + ) + }); + continue; + } + if (!site.exitNodeId) { logger.warn( `Site ${site.siteId} does not have exit node, skipping` @@ -103,26 +165,6 @@ export async function buildSiteConfigurationForOlmClient( relayEndpoint = `${exitNode.endpoint}:${config.getRawConfig().gerbil.clients_start_port}`; } - const allSiteResources = await db // only get the site resources that this client has access to - .select() - .from(siteResources) - .innerJoin( - clientSiteResourcesAssociationsCache, - eq( - siteResources.siteResourceId, - clientSiteResourcesAssociationsCache.siteResourceId - ) - ) - .where( - and( - eq(siteResources.siteId, site.siteId), - eq( - clientSiteResourcesAssociationsCache.clientId, - client.clientId - ) - ) - ); - // Add site configuration to the array siteConfigurations.push({ siteId: site.siteId, diff --git a/server/routers/olm/handleOlmRegisterMessage.ts b/server/routers/olm/handleOlmRegisterMessage.ts index 91a2aa138..68aa1b624 100644 --- a/server/routers/olm/handleOlmRegisterMessage.ts +++ b/server/routers/olm/handleOlmRegisterMessage.ts @@ -226,12 +226,12 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { // Prepare an array to store site configurations logger.debug(`Found ${sitesCount} sites for client ${client.clientId}`); - let jitMode = false; + let jitMode = true; if (sitesCount > 250 && build == "saas") { // THIS IS THE MAX ON THE BUSINESS TIER // we have too many sites // If we have too many sites we need to drop into fully JIT mode by not sending any of the sites - logger.info("Too many sites (%d), dropping into JIT mode", sitesCount) + logger.info("Too many sites (%d), dropping into JIT mode", sitesCount); jitMode = true; } @@ -277,25 +277,13 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { return; } - let siteConfigurations: { - siteId: number; - name: string; - endpoint: string; - publicKey: string | null; - serverIP: string | null; - serverPort: number | null; - remoteSubnets: string[]; - aliases: Alias[]; - }[] = []; - - if (!jitMode) { - // NOTE: its important that the client here is the old client and the public key is the new key - siteConfigurations = await buildSiteConfigurationForOlmClient( - client, - publicKey, - relay - ); - } + // NOTE: its important that the client here is the old client and the public key is the new key + const siteConfigurations = await buildSiteConfigurationForOlmClient( + client, + publicKey, + relay, + jitMode + ); // Return connect message with all site configurations return { From 7d0b3ec6b5dc02d8b7b1c35d44f3e4be0bbb423c Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:34:48 -0700 Subject: [PATCH 11/50] Fix not pulling wildcard cert updates --- server/lib/traefik/TraefikConfigManager.ts | 89 +++++++++++++++++++--- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/server/lib/traefik/TraefikConfigManager.ts b/server/lib/traefik/TraefikConfigManager.ts index 46d5ccc85..de9249291 100644 --- a/server/lib/traefik/TraefikConfigManager.ts +++ b/server/lib/traefik/TraefikConfigManager.ts @@ -218,10 +218,11 @@ export class TraefikConfigManager { return true; } - // Fetch if it's been more than 24 hours (for renewals) const dayInMs = 24 * 60 * 60 * 1000; const timeSinceLastFetch = Date.now() - this.lastCertificateFetch.getTime(); + + // Fetch if it's been more than 24 hours (daily routine check) if (timeSinceLastFetch > dayInMs) { logger.info("Fetching certificates due to 24-hour renewal check"); return true; @@ -265,7 +266,7 @@ export class TraefikConfigManager { return true; } - // Check if any local certificates are missing or appear to be outdated + // Check if any local certificates are missing (needs immediate fetch) for (const domain of domainsNeedingCerts) { const localState = this.lastLocalCertificateState.get(domain); if (!localState || !localState.exists) { @@ -274,17 +275,55 @@ export class TraefikConfigManager { ); return true; } + } - // Check if certificate is expiring soon (within 30 days) - if (localState.expiresAt) { - const nowInSeconds = Math.floor(Date.now() / 1000); - const secondsUntilExpiry = localState.expiresAt - nowInSeconds; - const daysUntilExpiry = secondsUntilExpiry / (60 * 60 * 24); - if (daysUntilExpiry < 30) { - logger.info( - `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` - ); - return true; + // For expiry checks, throttle to every 6 hours to avoid querying the + // API/DB on every monitor loop. The certificate-service renews certs + // 45 days before expiry, so checking every 6 hours is plenty frequent + // to pick up renewed certs promptly. + const renewalCheckIntervalMs = 6 * 60 * 60 * 1000; // 6 hours + if (timeSinceLastFetch > renewalCheckIntervalMs) { + // Check non-wildcard certs for expiry (within 45 days to match + // the server-side renewal window in certificate-service) + for (const domain of domainsNeedingCerts) { + const localState = + this.lastLocalCertificateState.get(domain); + if (localState?.expiresAt) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + localState.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } + } + } + + // Also check wildcard certificates for expiry. These are not + // included in domainsNeedingCerts since their subdomains are + // filtered out, so we must check them separately. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for wildcard cert ${certDomain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } } } } @@ -361,6 +400,32 @@ export class TraefikConfigManager { } } + // Also include wildcard cert base domains that are + // expiring or expired so they get re-fetched even though + // their subdomains were filtered out above. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor( + Date.now() / 1000 + ); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + domainsToFetch.add(certDomain); + logger.info( + `Including expiring wildcard cert domain ${certDomain} in fetch (${Math.round(daysUntilExpiry)} days remaining)` + ); + } + } + } + if (domainsToFetch.size > 0) { // Get valid certificates for domains not covered by wildcards validCertificates = From af688d2a232621c9f81a1357497446f74ea1ec79 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:04 -0700 Subject: [PATCH 12/50] Add demo link --- messages/en-US.json | 4 ++-- src/components/PaidFeaturesAlert.tsx | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index d84f4f337..6a35d79bb 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -2343,8 +2343,8 @@ "logRetentionEndOfFollowingYear": "End of following year", "actionLogsDescription": "View a history of actions performed in this organization", "accessLogsDescription": "View access auth requests for resources in this organization", - "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature.", - "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud.", + "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature. Book a demo or POC trial.", + "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud. Book a demo or POC trial.", "certResolver": "Certificate Resolver", "certResolverDescription": "Select the certificate resolver to use for this resource.", "selectCertResolver": "Select Certificate Resolver", diff --git a/src/components/PaidFeaturesAlert.tsx b/src/components/PaidFeaturesAlert.tsx index adbb49d9e..95179ea78 100644 --- a/src/components/PaidFeaturesAlert.tsx +++ b/src/components/PaidFeaturesAlert.tsx @@ -51,6 +51,7 @@ const docsLinkClassName = const PANGOLIN_CLOUD_SIGNUP_URL = "https://app.pangolin.net/auth/signup/"; const ENTERPRISE_DOCS_URL = "https://docs.pangolin.net/self-host/enterprise-edition"; +const BOOK_A_DEMO_URL = "https://click.fossorial.io/ep922"; function getTierLinkRenderer(billingHref: string) { return function tierLinkRenderer(chunks: React.ReactNode) { @@ -78,6 +79,22 @@ function getPangolinCloudLinkRenderer() { }; } +function getBookADemoLinkRenderer() { + return function bookADemoLinkRenderer(chunks: React.ReactNode) { + return ( + + {chunks} + + + ); + }; +} + function getDocsLinkRenderer(href: string) { return function docsLinkRenderer(chunks: React.ReactNode) { return ( @@ -116,6 +133,7 @@ export function PaidFeaturesAlert({ tiers }: Props) { const tierLinkRenderer = getTierLinkRenderer(billingHref); const pangolinCloudLinkRenderer = getPangolinCloudLinkRenderer(); const enterpriseDocsLinkRenderer = getDocsLinkRenderer(ENTERPRISE_DOCS_URL); + const bookADemoLinkRenderer = getBookADemoLinkRenderer(); if (env.flags.disableEnterpriseFeatures) { return null; @@ -157,7 +175,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("licenseRequiredToUse", { enterpriseLicenseLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })} @@ -174,7 +193,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("ossEnterpriseEditionRequired", { enterpriseEditionLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })} From 06015d51910d57463f8c5008de7ba50dc1e6c131 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:16 -0700 Subject: [PATCH 13/50] Handle gerbil rejecting 0 Closes #2605 --- server/lib/rebuildClientAssociations.ts | 4 ++-- server/routers/gerbil/getAllRelays.ts | 4 ++-- server/routers/gerbil/updateHolePunch.ts | 2 +- server/routers/newt/handleGetConfigMessage.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/lib/rebuildClientAssociations.ts b/server/lib/rebuildClientAssociations.ts index 625e57935..af43a6d00 100644 --- a/server/lib/rebuildClientAssociations.ts +++ b/server/lib/rebuildClientAssociations.ts @@ -571,7 +571,7 @@ export async function updateClientSiteDestinations( destinations: [ { destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } ] }; @@ -579,7 +579,7 @@ export async function updateClientSiteDestinations( // add to the existing destinations destinations.destinations.push({ destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } diff --git a/server/routers/gerbil/getAllRelays.ts b/server/routers/gerbil/getAllRelays.ts index b7d33b955..bbe314b2a 100644 --- a/server/routers/gerbil/getAllRelays.ts +++ b/server/routers/gerbil/getAllRelays.ts @@ -125,7 +125,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { // Add site as a destination for this client const destination: PeerDestination = { destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check if this destination is already in the array to avoid duplicates @@ -165,7 +165,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { const destination: PeerDestination = { destinationIP: peer.subnet.split("/")[0], - destinationPort: peer.listenPort + destinationPort: peer.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check for duplicates diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 3f24430bf..13d0ed276 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -262,7 +262,7 @@ export async function updateAndGenerateEndpointDestinations( if (site.subnet && site.listenPort) { destinations.push({ destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } } diff --git a/server/routers/newt/handleGetConfigMessage.ts b/server/routers/newt/handleGetConfigMessage.ts index 801c8b65a..24cca17a2 100644 --- a/server/routers/newt/handleGetConfigMessage.ts +++ b/server/routers/newt/handleGetConfigMessage.ts @@ -104,11 +104,11 @@ export const handleGetConfigMessage: MessageHandler = async (context) => { const payload = { oldDestination: { destinationIP: existingSite.subnet?.split("/")[0], - destinationPort: existingSite.listenPort + destinationPort: existingSite.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }, newDestination: { destinationIP: site.subnet?.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } }; From e9a2a7e75246ed0c8313a3d5ae5fd70ba3882bcd Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 20:46:27 -0700 Subject: [PATCH 14/50] Reorder delete --- server/lib/deleteOrg.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index cca2ea974..86c32e9a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -121,6 +121,9 @@ export async function deleteOrgById( eq(clientSitesAssociationsCache.clientId, client.clientId) ); } + + await trx.delete(resources).where(eq(resources.orgId, orgId)); + const allOrgDomains = await trx .select() .from(orgDomains) @@ -147,7 +150,6 @@ export async function deleteOrgById( .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); } - await trx.delete(resources).where(eq(resources.orgId, orgId)); await usageService.add(orgId, FeatureId.ORGINIZATIONS, -1, trx); // here we are decreasing the org count BEFORE deleting the org because we need to still be able to get the org to get the billing org inside of here From e98f873f8103aede2909527cfd43fce55b92e8b5 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 21:16:37 -0700 Subject: [PATCH 15/50] Clean up --- server/lib/deleteOrg.ts | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 86c32e9a1..56f2848a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -85,9 +85,7 @@ export async function deleteOrgById( deletedNewtIds.push(deletedNewt.newtId); await trx .delete(newtSessions) - .where( - eq(newtSessions.newtId, deletedNewt.newtId) - ); + .where(eq(newtSessions.newtId, deletedNewt.newtId)); } } } @@ -127,7 +125,7 @@ export async function deleteOrgById( const allOrgDomains = await trx .select() .from(orgDomains) - .innerJoin(domains, eq(domains.domainId, orgDomains.domainId)) + .innerJoin(domains, eq(orgDomains.domainId, domains.domainId)) .where( and( eq(orgDomains.orgId, orgId), @@ -136,16 +134,17 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domains.domainId; + const domainId = orgDomain.domainId; const orgCount = await trx - .select({ count: sql`count(*)` }) + .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count === 1) { + if (orgCount[0].count == 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { + // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); @@ -233,15 +232,13 @@ export function sendTerminationMessages(result: DeleteOrgByIdResult): void { ); } for (const olmId of result.olmsToTerminate) { - sendTerminateClient( - 0, - OlmErrorCodes.TERMINATED_REKEYED, - olmId - ).catch((error) => { - logger.error( - "Failed to send termination message to olm:", - error - ); - }); + sendTerminateClient(0, OlmErrorCodes.TERMINATED_REKEYED, olmId).catch( + (error) => { + logger.error( + "Failed to send termination message to olm:", + error + ); + } + ); } } From dec358c4cde83835612f83fe0d7c90ccde313882 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 10:03:49 -0700 Subject: [PATCH 16/50] Use native drizzle count --- server/lib/deleteOrg.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 56f2848a1..b32667d24 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -134,17 +134,16 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domainId; - const orgCount = await trx + const domainId = orgDomain.domains.domainId; + const [orgCount] = await trx .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count == 1) { + if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { - // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); From fa0818d3faac56a02fb98f7df2f9e8ae49172977 Mon Sep 17 00:00:00 2001 From: Shreyas Papinwar Date: Tue, 10 Mar 2026 12:01:24 +0530 Subject: [PATCH 17/50] fix: ensure Credenza dialog max-height --- src/components/Credenza.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Credenza.tsx b/src/components/Credenza.tsx index 63b847462..63b98c671 100644 --- a/src/components/Credenza.tsx +++ b/src/components/Credenza.tsx @@ -84,7 +84,7 @@ const CredenzaContent = ({ className, children, ...props }: CredenzaProps) => { return ( Date: Tue, 10 Mar 2026 14:24:57 -0700 Subject: [PATCH 18/50] Add some logging to debug --- server/lib/deleteOrg.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index b32667d24..065f216a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -132,6 +132,7 @@ export async function deleteOrgById( eq(domains.configManaged, false) ) ); + logger.info(`Found ${allOrgDomains.length} domains to delete`); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { const domainId = orgDomain.domains.domainId; @@ -139,10 +140,12 @@ export async function deleteOrgById( .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); + logger.info(`Found ${orgCount.count} orgs using domain ${domainId}`); if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } + logger.info(`Found ${domainIdsToDelete.length} domains to delete`); if (domainIdsToDelete.length > 0) { await trx .delete(domains) From 2ba225299e60c57a902a3cb950a17e3864749479 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 01:38:15 +0000 Subject: [PATCH 19/50] Bump the dev-minor-updates group across 1 directory with 5 updates Bumps the dev-minor-updates group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@dotenvx/dotenvx](https://github.com/dotenvx/dotenvx) | `1.52.0` | `1.53.0` | | [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) | `4.1.18` | `4.2.1` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.2.3` | `25.3.5` | | [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.1.18` | `4.2.1` | | [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.55.0` | `8.56.1` | Updates `@dotenvx/dotenvx` from 1.52.0 to 1.53.0 - [Release notes](https://github.com/dotenvx/dotenvx/releases) - [Changelog](https://github.com/dotenvx/dotenvx/blob/main/CHANGELOG.md) - [Commits](https://github.com/dotenvx/dotenvx/compare/v1.52.0...v1.53.0) Updates `@tailwindcss/postcss` from 4.1.18 to 4.2.1 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.1/packages/@tailwindcss-postcss) Updates `@types/node` from 25.2.3 to 25.3.5 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `tailwindcss` from 4.1.18 to 4.2.1 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.1/packages/tailwindcss) Updates `typescript-eslint` from 8.55.0 to 8.56.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: "@dotenvx/dotenvx" dependency-version: 1.53.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: "@tailwindcss/postcss" dependency-version: 4.2.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: "@types/node" dependency-version: 25.3.5 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: tailwindcss dependency-version: 4.2.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates - dependency-name: typescript-eslint dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-minor-updates ... Signed-off-by: dependabot[bot] --- package-lock.json | 489 ++++++++++++++++++++++++---------------------- package.json | 10 +- 2 files changed, 265 insertions(+), 234 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3e070b8ad..3fa1177d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -108,10 +108,10 @@ "zod-validation-error": "5.0.0" }, "devDependencies": { - "@dotenvx/dotenvx": "1.52.0", + "@dotenvx/dotenvx": "1.54.1", "@esbuild-plugins/tsconfig-paths": "0.1.2", "@react-email/preview-server": "5.2.8", - "@tailwindcss/postcss": "4.1.18", + "@tailwindcss/postcss": "4.2.1", "@tanstack/react-query-devtools": "5.91.3", "@types/better-sqlite3": "7.6.13", "@types/cookie-parser": "1.4.10", @@ -123,7 +123,7 @@ "@types/jmespath": "0.15.2", "@types/js-yaml": "4.0.9", "@types/jsonwebtoken": "9.0.10", - "@types/node": "25.2.3", + "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", "@types/pg": "8.16.0", @@ -144,11 +144,11 @@ "postcss": "8.5.6", "prettier": "3.8.1", "react-email": "5.2.8", - "tailwindcss": "4.1.18", + "tailwindcss": "4.2.1", "tsc-alias": "1.8.16", "tsx": "4.21.0", "typescript": "5.9.3", - "typescript-eslint": "8.55.0" + "typescript-eslint": "8.56.1" } }, "node_modules/@alloc/quick-lru": { @@ -1454,9 +1454,9 @@ "license": "MIT" }, "node_modules/@dotenvx/dotenvx": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.52.0.tgz", - "integrity": "sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w==", + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.54.1.tgz", + "integrity": "sha512-41gU3q7v05GM92QPuPUf4CmUw+mmF8p4wLUh6MCRlxpCkJ9ByLcY9jUf6MwrMNmiKyG/rIckNxj9SCfmNCmCqw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -8960,49 +8960,49 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", - "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.3", + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.30.2", + "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.18" + "tailwindcss": "4.2.1" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", - "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-x64": "4.1.18", - "@tailwindcss/oxide-freebsd-x64": "4.1.18", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-x64-musl": "4.1.18", - "@tailwindcss/oxide-wasm32-wasi": "4.1.18", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", - "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", "cpu": [ "arm64" ], @@ -9013,13 +9013,13 @@ "android" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", - "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", "cpu": [ "arm64" ], @@ -9030,13 +9030,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", - "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", "cpu": [ "x64" ], @@ -9047,13 +9047,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", - "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", "cpu": [ "x64" ], @@ -9064,13 +9064,13 @@ "freebsd" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", - "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", "cpu": [ "arm" ], @@ -9081,13 +9081,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", - "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", "cpu": [ "arm64" ], @@ -9098,13 +9098,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", - "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", "cpu": [ "arm64" ], @@ -9115,13 +9115,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", - "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", "cpu": [ "x64" ], @@ -9132,13 +9132,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", - "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", "cpu": [ "x64" ], @@ -9149,13 +9149,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", - "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -9171,19 +9171,19 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.4.0" + "tslib": "^2.8.1" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.7.1", + "version": "1.8.1", "dev": true, "inBundle": true, "license": "MIT", @@ -9194,7 +9194,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.7.1", + "version": "1.8.1", "dev": true, "inBundle": true, "license": "MIT", @@ -9214,7 +9214,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.0", + "version": "1.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -9223,6 +9223,10 @@ "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { @@ -9243,9 +9247,9 @@ "optional": true }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", - "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", "cpu": [ "arm64" ], @@ -9256,13 +9260,13 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", - "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", "cpu": [ "x64" ], @@ -9273,21 +9277,21 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", - "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.2.1.tgz", + "integrity": "sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==", "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.18", - "@tailwindcss/oxide": "4.1.18", - "postcss": "^8.4.41", - "tailwindcss": "4.1.18" + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "postcss": "^8.5.6", + "tailwindcss": "4.2.1" } }, "node_modules/@tanstack/query-core": { @@ -9860,12 +9864,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", - "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", + "version": "25.3.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz", + "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", "devOptional": true, + "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/nodemailer": { @@ -10043,16 +10048,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", - "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/type-utils": "8.55.0", - "@typescript-eslint/utils": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -10065,8 +10071,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.55.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -10075,20 +10081,22 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", - "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "engines": { @@ -10099,18 +10107,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", - "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.55.0", - "@typescript-eslint/types": "^8.55.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -10125,13 +10134,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10142,10 +10152,11 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", - "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -10158,14 +10169,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", - "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -10177,15 +10189,16 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -10195,17 +10208,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -10232,9 +10246,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { @@ -10245,31 +10259,32 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", - "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10279,18 +10294,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10300,6 +10316,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", @@ -13533,14 +13562,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.4", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", - "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -16226,9 +16255,9 @@ } }, "node_modules/lightningcss": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -16242,23 +16271,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.30.2", - "lightningcss-darwin-arm64": "1.30.2", - "lightningcss-darwin-x64": "1.30.2", - "lightningcss-freebsd-x64": "1.30.2", - "lightningcss-linux-arm-gnueabihf": "1.30.2", - "lightningcss-linux-arm64-gnu": "1.30.2", - "lightningcss-linux-arm64-musl": "1.30.2", - "lightningcss-linux-x64-gnu": "1.30.2", - "lightningcss-linux-x64-musl": "1.30.2", - "lightningcss-win32-arm64-msvc": "1.30.2", - "lightningcss-win32-x64-msvc": "1.30.2" + "lightningcss-android-arm64": "1.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", "cpu": [ "arm64" ], @@ -16277,9 +16306,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", "cpu": [ "arm64" ], @@ -16298,9 +16327,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", "cpu": [ "x64" ], @@ -16319,9 +16348,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", "cpu": [ "x64" ], @@ -16340,9 +16369,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", "cpu": [ "arm" ], @@ -16361,9 +16390,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", "cpu": [ "arm64" ], @@ -16382,9 +16411,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", "cpu": [ "arm64" ], @@ -16403,9 +16432,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", "cpu": [ "x64" ], @@ -16424,9 +16453,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", "cpu": [ "x64" ], @@ -16445,9 +16474,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", "cpu": [ "arm64" ], @@ -16466,9 +16495,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", "cpu": [ "x64" ], @@ -20741,9 +20770,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", - "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", "license": "MIT" }, "node_modules/tapable": { @@ -20891,6 +20920,7 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.12" }, @@ -21227,15 +21257,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.55.0.tgz", - "integrity": "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.1.tgz", + "integrity": "sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.55.0", - "@typescript-eslint/parser": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0" + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -21245,7 +21276,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -21282,9 +21313,9 @@ } }, "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==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "devOptional": true, "license": "MIT" }, diff --git a/package.json b/package.json index df92d1a64..f0bb0b9b4 100644 --- a/package.json +++ b/package.json @@ -131,10 +131,10 @@ "zod-validation-error": "5.0.0" }, "devDependencies": { - "@dotenvx/dotenvx": "1.52.0", + "@dotenvx/dotenvx": "1.54.1", "@esbuild-plugins/tsconfig-paths": "0.1.2", "@react-email/preview-server": "5.2.8", - "@tailwindcss/postcss": "4.1.18", + "@tailwindcss/postcss": "4.2.1", "@tanstack/react-query-devtools": "5.91.3", "@types/better-sqlite3": "7.6.13", "@types/cookie-parser": "1.4.10", @@ -146,7 +146,7 @@ "@types/jmespath": "0.15.2", "@types/js-yaml": "4.0.9", "@types/jsonwebtoken": "9.0.10", - "@types/node": "25.2.3", + "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", "@types/pg": "8.16.0", @@ -167,10 +167,10 @@ "postcss": "8.5.6", "prettier": "3.8.1", "react-email": "5.2.8", - "tailwindcss": "4.1.18", + "tailwindcss": "4.2.1", "tsc-alias": "1.8.16", "tsx": "4.21.0", "typescript": "5.9.3", - "typescript-eslint": "8.55.0" + "typescript-eslint": "8.56.1" } } From 42b9d5158dde72b895e2de10a9ae8ee7c590daab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 01:40:39 +0000 Subject: [PATCH 20/50] Bump the prod-minor-updates group across 1 directory with 10 updates Bumps the prod-minor-updates group with 10 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) | `3.989.0` | `3.1003.0` | | [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) | `8.2.1` | `8.3.0` | | [ioredis](https://github.com/luin/ioredis) | `5.9.3` | `5.10.0` | | [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.563.0` | `0.577.0` | | [pg](https://github.com/brianc/node-postgres/tree/HEAD/packages/pg) | `8.19.0` | `8.20.0` | | [posthog-node](https://github.com/PostHog/posthog-js/tree/HEAD/packages/node) | `5.26.0` | `5.28.0` | | [react-day-picker](https://github.com/gpbl/react-day-picker) | `9.13.2` | `9.14.0` | | [react-icons](https://github.com/react-icons/react-icons) | `5.5.0` | `5.6.0` | | reodotdev | `1.0.0` | `1.1.0` | | [stripe](https://github.com/stripe/stripe-node) | `20.3.1` | `20.4.0` | Updates `@aws-sdk/client-s3` from 3.989.0 to 3.1003.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1003.0/clients/client-s3) Updates `express-rate-limit` from 8.2.1 to 8.3.0 - [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases) - [Commits](https://github.com/express-rate-limit/express-rate-limit/compare/v8.2.1...v8.3.0) Updates `ioredis` from 5.9.3 to 5.10.0 - [Release notes](https://github.com/luin/ioredis/releases) - [Changelog](https://github.com/redis/ioredis/blob/main/CHANGELOG.md) - [Commits](https://github.com/luin/ioredis/compare/v5.9.3...v5.10.0) Updates `lucide-react` from 0.563.0 to 0.577.0 - [Release notes](https://github.com/lucide-icons/lucide/releases) - [Commits](https://github.com/lucide-icons/lucide/commits/0.577.0/packages/lucide-react) Updates `pg` from 8.19.0 to 8.20.0 - [Changelog](https://github.com/brianc/node-postgres/blob/master/CHANGELOG.md) - [Commits](https://github.com/brianc/node-postgres/commits/pg@8.20.0/packages/pg) Updates `posthog-node` from 5.26.0 to 5.28.0 - [Release notes](https://github.com/PostHog/posthog-js/releases) - [Changelog](https://github.com/PostHog/posthog-js/blob/main/packages/node/CHANGELOG.md) - [Commits](https://github.com/PostHog/posthog-js/commits/posthog-node@5.28.0/packages/node) Updates `react-day-picker` from 9.13.2 to 9.14.0 - [Release notes](https://github.com/gpbl/react-day-picker/releases) - [Changelog](https://github.com/gpbl/react-day-picker/blob/main/CHANGELOG.md) - [Commits](https://github.com/gpbl/react-day-picker/compare/v9.13.2...v9.14.0) Updates `react-icons` from 5.5.0 to 5.6.0 - [Release notes](https://github.com/react-icons/react-icons/releases) - [Commits](https://github.com/react-icons/react-icons/compare/v5.5.0...v5.6.0) Updates `reodotdev` from 1.0.0 to 1.1.0 Updates `stripe` from 20.3.1 to 20.4.0 - [Release notes](https://github.com/stripe/stripe-node/releases) - [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/stripe/stripe-node/compare/v20.3.1...v20.4.0) --- updated-dependencies: - dependency-name: "@aws-sdk/client-s3" dependency-version: 3.1003.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: express-rate-limit dependency-version: 8.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: ioredis dependency-version: 5.10.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: lucide-react dependency-version: 0.577.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: pg dependency-version: 8.20.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: posthog-node dependency-version: 5.28.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: react-day-picker dependency-version: 9.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: react-icons dependency-version: 5.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: reodotdev dependency-version: 1.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates - dependency-name: stripe dependency-version: 20.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: prod-minor-updates ... Signed-off-by: dependabot[bot] --- package-lock.json | 1464 +++++++++++++++++++++++---------------------- package.json | 22 +- 2 files changed, 766 insertions(+), 720 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3fa1177d5..9e3b0e759 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "SEE LICENSE IN LICENSE AND README.md", "dependencies": { "@asteasolutions/zod-to-openapi": "8.4.1", - "@aws-sdk/client-s3": "3.989.0", + "@aws-sdk/client-s3": "3.1004.0", "@faker-js/faker": "10.3.0", "@headlessui/react": "2.2.9", "@hookform/resolvers": "5.2.2", @@ -57,16 +57,16 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.2", + "express-rate-limit": "8.3.0", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", "input-otp": "1.4.2", - "ioredis": "5.9.3", + "ioredis": "5.10.0", "jmespath": "0.16.0", "js-yaml": "4.1.1", "jsonwebtoken": "9.0.3", - "lucide-react": "0.563.0", + "lucide-react": "0.577.0", "maxmind": "5.0.5", "moment": "2.30.1", "next": "15.5.12", @@ -76,21 +76,21 @@ "node-cache": "5.1.2", "nodemailer": "8.0.1", "oslo": "1.2.1", - "pg": "8.19.0", - "posthog-node": "5.26.0", + "pg": "8.20.0", + "posthog-node": "5.28.0", "qrcode.react": "4.2.0", "react": "19.2.4", - "react-day-picker": "9.13.2", + "react-day-picker": "9.14.0", "react-dom": "19.2.4", "react-easy-sort": "1.8.0", "react-hook-form": "7.71.2", - "react-icons": "5.5.0", + "react-icons": "5.6.0", "recharts": "2.15.4", - "reodotdev": "1.0.0", + "reodotdev": "1.1.0", "resend": "6.9.2", "semver": "7.7.4", "sshpk": "^1.18.0", - "stripe": "20.3.1", + "stripe": "20.4.1", "swagger-ui-express": "5.0.1", "tailwind-merge": "3.5.0", "topojson-client": "3.1.0", @@ -126,7 +126,7 @@ "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", - "@types/pg": "8.16.0", + "@types/pg": "8.18.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@types/semver": "7.7.1", @@ -208,6 +208,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -270,6 +271,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", @@ -284,6 +286,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -295,6 +298,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" @@ -307,6 +311,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" @@ -319,6 +324,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", @@ -387,112 +393,65 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.989.0.tgz", - "integrity": "sha512-ccz2miIetWAgrJYmKCpSnRjF8jew7DPstl54nufhfPMtM1MLxD2z55eSk1eJj3Umhu4CioNN1aY1ILT7fwlSiw==", + "version": "3.1004.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1004.0.tgz", + "integrity": "sha512-m0zNfpsona9jQdX1cHtHArOiuvSGZPsgp/KRZS2YjJhKah96G2UN3UNGZQ6aVjXIQjCY6UanCJo0uW9Xf2U41w==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/credential-provider-node": "^3.972.8", - "@aws-sdk/middleware-bucket-endpoint": "^3.972.3", - "@aws-sdk/middleware-expect-continue": "^3.972.3", - "@aws-sdk/middleware-flexible-checksums": "^3.972.7", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-location-constraint": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-sdk-s3": "^3.972.9", - "@aws-sdk/middleware-ssec": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/signature-v4-multi-region": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.23.0", - "@smithy/eventstream-serde-browser": "^4.2.8", - "@smithy/eventstream-serde-config-resolver": "^4.3.8", - "@smithy/eventstream-serde-node": "^4.2.8", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-blob-browser": "^4.2.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/hash-stream-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/md5-js": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-retry": "^4.4.31", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.30", - "@smithy/util-defaults-mode-node": "^4.2.33", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", - "@smithy/util-waiter": "^4.2.8", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.989.0.tgz", - "integrity": "sha512-3sC+J1ru5VFXLgt9KZmXto0M7mnV5RkS6FNGwRMK3XrojSjHso9DLOWjbnXhbNv4motH8vu53L1HK2VC1+Nj5w==", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.23.0", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-retry": "^4.4.31", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.30", - "@smithy/util-defaults-mode-node": "^4.2.33", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/credential-provider-node": "^3.972.18", + "@aws-sdk/middleware-bucket-endpoint": "^3.972.7", + "@aws-sdk/middleware-expect-continue": "^3.972.7", + "@aws-sdk/middleware-flexible-checksums": "^3.973.4", + "@aws-sdk/middleware-host-header": "^3.972.7", + "@aws-sdk/middleware-location-constraint": "^3.972.7", + "@aws-sdk/middleware-logger": "^3.972.7", + "@aws-sdk/middleware-recursion-detection": "^3.972.7", + "@aws-sdk/middleware-sdk-s3": "^3.972.18", + "@aws-sdk/middleware-ssec": "^3.972.7", + "@aws-sdk/middleware-user-agent": "^3.972.19", + "@aws-sdk/region-config-resolver": "^3.972.7", + "@aws-sdk/signature-v4-multi-region": "^3.996.6", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@aws-sdk/util-user-agent-browser": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.973.4", + "@smithy/config-resolver": "^4.4.10", + "@smithy/core": "^3.23.8", + "@smithy/eventstream-serde-browser": "^4.2.11", + "@smithy/eventstream-serde-config-resolver": "^4.3.11", + "@smithy/eventstream-serde-node": "^4.2.11", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/hash-blob-browser": "^4.2.12", + "@smithy/hash-node": "^4.2.11", + "@smithy/hash-stream-node": "^4.2.11", + "@smithy/invalid-dependency": "^4.2.11", + "@smithy/md5-js": "^4.2.11", + "@smithy/middleware-content-length": "^4.2.11", + "@smithy/middleware-endpoint": "^4.4.22", + "@smithy/middleware-retry": "^4.4.39", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.38", + "@smithy/util-defaults-mode-node": "^4.2.41", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -500,22 +459,23 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.973.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.9.tgz", - "integrity": "sha512-cyUOfJSizn8da7XrBEFBf4UMI4A6JQNX6ZFcKtYmh/CrwfzsDcabv3k/z0bNwQ3pX5aeq5sg/8Bs/ASiL0bJaA==", + "version": "3.973.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.18.tgz", + "integrity": "sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/xml-builder": "^3.972.4", - "@smithy/core": "^3.23.0", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/xml-builder": "^3.972.10", + "@smithy/core": "^3.23.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/signature-v4": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -523,11 +483,12 @@ } }, "node_modules/@aws-sdk/crc64-nvme": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.0.tgz", - "integrity": "sha512-ThlLhTqX68jvoIVv+pryOdb5coP1cX1/MaTbB9xkGDCbWbsqQcLqzPxuSoW1DCnAAIacmXCWpzUNOB9pv+xXQw==", + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.4.tgz", + "integrity": "sha512-HKZIZLbRyvzo/bXZU7Zmk6XqU+1C9DjI56xd02vwuDIxedxBEqP17t9ExhbP9QFeNq/a3l9GOcyirFXxmbDhmw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -535,14 +496,15 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.7.tgz", - "integrity": "sha512-r8kBtglvLjGxBT87l6Lqkh9fL8yJJ6O4CYQPjKlj3AkCuL4/4784x3rxxXWw9LTKXOo114VB6mjxAuy5pI7XIg==", + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.16.tgz", + "integrity": "sha512-HrdtnadvTGAQUr18sPzGlE5El3ICphnH6SU7UQOMOWFgRKbTRNN8msTxM4emzguUso9CzaHU2xy5ctSrmK5YNA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -550,19 +512,20 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.9.tgz", - "integrity": "sha512-40caFblEg/TPrp9EpvyMxp4xlJ5TuTI+A8H6g8FhHn2hfH2PObFAPLF9d5AljK/G69E1YtTklkuQeAwPlV3w8Q==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.18.tgz", + "integrity": "sha512-NyB6smuZAixND5jZumkpkunQ0voc4Mwgkd+SZ6cvAzIB7gK8HV8Zd4rS8Kn5MmoGgusyNfVGG+RLoYc4yFiw+A==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.12", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" }, "engines": { @@ -570,23 +533,24 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.7.tgz", - "integrity": "sha512-zeYKrMwM5bCkHFho/x3+1OL0vcZQ0OhTR7k35tLq74+GP5ieV3juHXTZfa2LVE0Bg75cHIIerpX0gomVOhzo/w==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.17.tgz", + "integrity": "sha512-dFqh7nfX43B8dO1aPQHOcjC0SnCJ83H3F+1LoCh3X1P7E7N09I+0/taID0asU6GCddfDExqnEvQtDdkuMe5tKQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/credential-provider-env": "^3.972.7", - "@aws-sdk/credential-provider-http": "^3.972.9", - "@aws-sdk/credential-provider-login": "^3.972.7", - "@aws-sdk/credential-provider-process": "^3.972.7", - "@aws-sdk/credential-provider-sso": "^3.972.7", - "@aws-sdk/credential-provider-web-identity": "^3.972.7", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/credential-provider-env": "^3.972.16", + "@aws-sdk/credential-provider-http": "^3.972.18", + "@aws-sdk/credential-provider-login": "^3.972.17", + "@aws-sdk/credential-provider-process": "^3.972.16", + "@aws-sdk/credential-provider-sso": "^3.972.17", + "@aws-sdk/credential-provider-web-identity": "^3.972.17", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -594,17 +558,18 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.7.tgz", - "integrity": "sha512-Q103cLU6OjAllYjX7+V+PKQw654jjvZUkD+lbUUiFbqut6gR5zwl1DrelvJPM5hnzIty7BCaxaRB3KMuz3M/ug==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.17.tgz", + "integrity": "sha512-gf2E5b7LpKb+JX2oQsRIDxdRZjBFZt2olCGlWCdb3vBERbXIPgm2t1R5mEnwd4j0UEO/Tbg5zN2KJbHXttJqwA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -612,21 +577,22 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.8.tgz", - "integrity": "sha512-AaDVOT7iNJyLjc3j91VlucPZ4J8Bw+eu9sllRDugJqhHWYyR3Iyp2huBUW8A3+DfHoh70sxGkY92cThAicSzlQ==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.18.tgz", + "integrity": "sha512-ZDJa2gd1xiPg/nBDGhUlat02O8obaDEnICBAVS8qieZ0+nDfaB0Z3ec6gjZj27OqFTjnB/Q5a0GwQwb7rMVViw==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.7", - "@aws-sdk/credential-provider-http": "^3.972.9", - "@aws-sdk/credential-provider-ini": "^3.972.7", - "@aws-sdk/credential-provider-process": "^3.972.7", - "@aws-sdk/credential-provider-sso": "^3.972.7", - "@aws-sdk/credential-provider-web-identity": "^3.972.7", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/credential-provider-env": "^3.972.16", + "@aws-sdk/credential-provider-http": "^3.972.18", + "@aws-sdk/credential-provider-ini": "^3.972.17", + "@aws-sdk/credential-provider-process": "^3.972.16", + "@aws-sdk/credential-provider-sso": "^3.972.17", + "@aws-sdk/credential-provider-web-identity": "^3.972.17", + "@aws-sdk/types": "^3.973.5", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -634,15 +600,16 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.7.tgz", - "integrity": "sha512-hxMo1V3ujWWrQSONxQJAElnjredkRpB6p8SDjnvRq70IwYY38R/CZSys0IbhRPxdgWZ5j12yDRk2OXhxw4Gj3g==", + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.16.tgz", + "integrity": "sha512-n89ibATwnLEg0ZdZmUds5bq8AfBAdoYEDpqP3uzPLaRuGelsKlIvCYSNNvfgGLi8NaHPNNhs1HjJZYbqkW9b+g==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -650,17 +617,18 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.7.tgz", - "integrity": "sha512-ZGKBOHEj8Ap15jhG2XMncQmKLTqA++2DVU2eZfLu3T/pkwDyhCp5eZv5c/acFxbZcA/6mtxke+vzO/n+aeHs4A==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.17.tgz", + "integrity": "sha512-wGtte+48xnhnhHMl/MsxzacBPs5A+7JJedjiP452IkHY7vsbYKcvQBqFye8LwdTJVeHtBHv+JFeTscnwepoWGg==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.989.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/token-providers": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/token-providers": "3.1004.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -668,16 +636,17 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.7.tgz", - "integrity": "sha512-AbYupBIoSJoVMlbMqBhNvPhqj+CdGtzW7Uk4ZIMBm2br18pc3rkG1VaKVFV85H87QCvLHEnni1idJjaX1wOmIw==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.17.tgz", + "integrity": "sha512-8aiVJh6fTdl8gcyL+sVNcNwTtWpmoFa1Sh7xlj6Z7L/cZ/tYMEBHq44wTYG8Kt0z/PpGNopD89nbj3FHl9QmTA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -685,17 +654,17 @@ } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.3.tgz", - "integrity": "sha512-fmbgWYirF67YF1GfD7cg5N6HHQ96EyRNx/rDIrTF277/zTWVuPI2qS/ZHgofwR1NZPe/NWvoppflQY01LrbVLg==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.7.tgz", + "integrity": "sha512-goX+axlJ6PQlRnzE2bQisZ8wVrlm6dXJfBzMJhd8LhAIBan/w1Kl73fJnalM/S+18VnpzIHumyV6DtgmvqG5IA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-arn-parser": "^3.972.2", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -703,14 +672,14 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.3.tgz", - "integrity": "sha512-4msC33RZsXQpUKR5QR4HnvBSNCPLGHmB55oDiROqqgyOc+TOfVu2xgi5goA7ms6MdZLeEh2905UfWMnMMF4mRg==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.7.tgz", + "integrity": "sha512-mvWqvm61bmZUKmmrtl2uWbokqpenY3Mc3Jf4nXB/Hse6gWxLPaCQThmhPBDzsPSV8/Odn8V6ovWt3pZ7vy4BFQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -718,23 +687,24 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.7.tgz", - "integrity": "sha512-YU/5rpz8k2mwFGi2M0px9ChOQZY7Bbow5knB2WLRVPqDM/cG8T5zj55UaWS1qcaFpE7vCX9a9/kvYBlKGcD+KA==", + "version": "3.973.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.973.4.tgz", + "integrity": "sha512-7CH2jcGmkvkHc5Buz9IGbdjq1729AAlgYJiAvGq7qhCHqYleCsriWdSnmsqWTwdAfXHMT+pkxX3w6v5tJNcSug==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/crc64-nvme": "3.972.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/is-array-buffer": "^4.2.0", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/crc64-nvme": "^3.972.4", + "@aws-sdk/types": "^3.973.5", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -742,13 +712,14 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.3.tgz", - "integrity": "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.7.tgz", + "integrity": "sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -756,13 +727,13 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.3.tgz", - "integrity": "sha512-nIg64CVrsXp67vbK0U1/Is8rik3huS3QkRHn2DRDx4NldrEFMgdkZGI/+cZMKD9k4YOS110Dfu21KZLHrFA/1g==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.7.tgz", + "integrity": "sha512-vdK1LJfffBp87Lj0Bw3WdK1rJk9OLDYdQpqoKgmpIZPe+4+HawZ6THTbvjhJt4C4MNnRrHTKHQjkwBiIpDBoig==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -770,12 +741,13 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.3.tgz", - "integrity": "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.7.tgz", + "integrity": "sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -783,14 +755,15 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.3.tgz", - "integrity": "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.7.tgz", + "integrity": "sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", + "@aws-sdk/types": "^3.973.5", "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -798,23 +771,24 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.9.tgz", - "integrity": "sha512-F4Ak2HM7te/o3izFTqg/jUTBLjavpaJ5iynKM6aLMwNddXbwAZQ1VbIG8RFUHBo7fBHj2eeN2FNLtIFT4ejWYQ==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.18.tgz", + "integrity": "sha512-5E3XxaElrdyk6ZJ0TjH7Qm6ios4b/qQCiLr6oQ8NK7e4Kn6JBTJCaYioQCQ65BpZ1+l1mK5wTAac2+pEz0Smpw==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-arn-parser": "^3.972.2", - "@smithy/core": "^3.23.0", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/core": "^3.23.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/signature-v4": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -822,13 +796,13 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.3.tgz", - "integrity": "sha512-dU6kDuULN3o3jEHcjm0c4zWJlY1zWVkjG9NPe9qxYLLpcbdj5kRYBS2DdWYD+1B9f910DezRuws7xDEqKkHQIg==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.7.tgz", + "integrity": "sha512-G9clGVuAml7d8DYzY6DnRi7TIIDRvZ3YpqJPz/8wnWS5fYx/FNWNmkO6iJVlVkQg9BfeMzd+bVPtPJOvC4B+nQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -836,16 +810,18 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.9.tgz", - "integrity": "sha512-1g1B7yf7KzessB0mKNiV9gAHEwbM662xgU+VE4LxyGe6kVGZ8LqYsngjhE+Stna09CJ7Pxkjr6Uq1OtbGwJJJg==", + "version": "3.972.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.19.tgz", + "integrity": "sha512-Km90fcXt3W/iqujHzuM6IaDkYCj73gsYufcuWXApWdzoTy6KGk8fnchAjePMARU0xegIR3K4N3yIo1vy7OVe8A==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@smithy/core": "^3.23.0", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@smithy/core": "^3.23.8", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-retry": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -853,47 +829,48 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.989.0.tgz", - "integrity": "sha512-Dbk2HMPU3mb6RrSRzgf0WCaWSbgtZG258maCpuN2/ONcAQNpOTw99V5fU5CA1qVK6Vkm4Fwj2cnOnw7wbGVlOw==", + "version": "3.996.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.7.tgz", + "integrity": "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg==", + "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/middleware-host-header": "^3.972.3", - "@aws-sdk/middleware-logger": "^3.972.3", - "@aws-sdk/middleware-recursion-detection": "^3.972.3", - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/region-config-resolver": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.989.0", - "@aws-sdk/util-user-agent-browser": "^3.972.3", - "@aws-sdk/util-user-agent-node": "^3.972.7", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.23.0", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-retry": "^4.4.31", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.30", - "@smithy/util-defaults-mode-node": "^4.2.33", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/middleware-host-header": "^3.972.7", + "@aws-sdk/middleware-logger": "^3.972.7", + "@aws-sdk/middleware-recursion-detection": "^3.972.7", + "@aws-sdk/middleware-user-agent": "^3.972.19", + "@aws-sdk/region-config-resolver": "^3.972.7", + "@aws-sdk/types": "^3.973.5", + "@aws-sdk/util-endpoints": "^3.996.4", + "@aws-sdk/util-user-agent-browser": "^3.972.7", + "@aws-sdk/util-user-agent-node": "^3.973.4", + "@smithy/config-resolver": "^4.4.10", + "@smithy/core": "^3.23.8", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/hash-node": "^4.2.11", + "@smithy/invalid-dependency": "^4.2.11", + "@smithy/middleware-content-length": "^4.2.11", + "@smithy/middleware-endpoint": "^4.4.22", + "@smithy/middleware-retry": "^4.4.39", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/protocol-http": "^5.3.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.38", + "@smithy/util-defaults-mode-node": "^4.2.41", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -901,14 +878,15 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.3.tgz", - "integrity": "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.7.tgz", + "integrity": "sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/config-resolver": "^4.4.10", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -916,15 +894,16 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.989.0.tgz", - "integrity": "sha512-rVhR/BUZdnru7tLlxWD+uzoKB1LAs2L0pcoh6rYgIYuCtQflnsC6Ud0SpfqIsOapBSBKXdoW73IITFf+XFMdCQ==", + "version": "3.996.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.6.tgz", + "integrity": "sha512-NnsOQsVmJXy4+IdPFUjRCWPn9qNH1TzS/f7MiWgXeoHs903tJpAWQWQtoFvLccyPoBgomKP9L89RRr2YsT/L0g==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "^3.972.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/middleware-sdk-s3": "^3.972.18", + "@aws-sdk/types": "^3.973.5", + "@smithy/protocol-http": "^5.3.11", + "@smithy/signature-v4": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -932,16 +911,17 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.989.0.tgz", - "integrity": "sha512-OdBByMv+OjOZoekrk4THPFpLuND5aIQbDHCGh3n2rvifAbm31+6e0OLhxSeCF1UMPm+nKq12bXYYEoCIx5SQBg==", + "version": "3.1004.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1004.0.tgz", + "integrity": "sha512-j9BwZZId9sFp+4GPhf6KrwO8Tben2sXibZA8D1vv2I1zBdvkUHcBA2g4pkqIpTRalMTLC0NPkBPX0gERxfy/iA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.9", - "@aws-sdk/nested-clients": "3.989.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.18", + "@aws-sdk/nested-clients": "^3.996.7", + "@aws-sdk/types": "^3.973.5", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -949,12 +929,12 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.973.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.1.tgz", - "integrity": "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==", + "version": "3.973.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.5.tgz", + "integrity": "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -962,9 +942,9 @@ } }, "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.2.tgz", - "integrity": "sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.3.tgz", + "integrity": "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -974,14 +954,15 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.989.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.989.0.tgz", - "integrity": "sha512-eKmAOeQM4Qusq0jtcbZPiNWky8XaojByKC/n+THbJ8vJf7t4ys8LlcZ4PrBSHZISe9cC484mQsPVOQh6iySjqw==", + "version": "3.996.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.4.tgz", + "integrity": "sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-endpoints": "^3.2.8", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-endpoints": "^3.3.2", "tslib": "^2.6.2" }, "engines": { @@ -1001,25 +982,27 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.3.tgz", - "integrity": "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==", + "version": "3.972.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.7.tgz", + "integrity": "sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.5", + "@smithy/types": "^4.13.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.972.7", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.7.tgz", - "integrity": "sha512-oyhv+FjrgHjP+F16cmsrJzNP4qaRJzkV1n9Lvv4uyh3kLqo3rIe9NSBSBa35f2TedczfG2dD+kaQhHBB47D6Og==", + "version": "3.973.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.4.tgz", + "integrity": "sha512-uqKeLqZ9D3nQjH7HGIERNXK9qnSpUK08l4MlJ5/NZqSSdeJsVANYp437EM9sEzwU28c2xfj2V6qlkqzsgtKs6Q==", + "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.9", - "@aws-sdk/types": "^3.973.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/middleware-user-agent": "^3.972.19", + "@aws-sdk/types": "^3.973.5", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1052,6 +1035,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.3.tgz", "integrity": "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==", + "license": "Apache-2.0", "engines": { "node": ">=18.0.0" } @@ -3221,9 +3205,9 @@ } }, "node_modules/@ioredis/commands": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz", - "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz", + "integrity": "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==", "license": "MIT" }, "node_modules/@isaacs/cliui": { @@ -4599,9 +4583,9 @@ } }, "node_modules/@posthog/core": { - "version": "1.23.1", - "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.1.tgz", - "integrity": "sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ==", + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.2.tgz", + "integrity": "sha512-zTDdda9NuSHrnwSOfFMxX/pyXiycF4jtU1kTr8DL61dHhV+7LF6XF1ndRZZTuaGGbfbb/GJYkEsjEX9SXfNZeQ==", "license": "MIT", "dependencies": { "cross-spawn": "^7.0.6" @@ -7993,12 +7977,12 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", - "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.11.tgz", + "integrity": "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8006,9 +7990,9 @@ } }, "node_modules/@smithy/chunked-blob-reader": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.0.tgz", - "integrity": "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.2.tgz", + "integrity": "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8018,12 +8002,12 @@ } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.1.tgz", - "integrity": "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.3.tgz", + "integrity": "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-base64": "^4.3.0", + "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -8031,15 +8015,16 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", - "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.10.tgz", + "integrity": "sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -8047,19 +8032,20 @@ } }, "node_modules/@smithy/core": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.0.tgz", - "integrity": "sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg==", + "version": "3.23.9", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.9.tgz", + "integrity": "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.2.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.12", - "@smithy/util-utf8": "^4.2.0", - "@smithy/uuid": "^1.1.0", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" }, "engines": { @@ -8067,14 +8053,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", - "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.11.tgz", + "integrity": "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -8082,14 +8069,14 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.8.tgz", - "integrity": "sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.11.tgz", + "integrity": "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8097,13 +8084,13 @@ } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.8.tgz", - "integrity": "sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.11.tgz", + "integrity": "sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-serde-universal": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8111,12 +8098,12 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.8.tgz", - "integrity": "sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.11.tgz", + "integrity": "sha512-XeNIA8tcP/GDWnnKkO7qEm/bg0B/bP9lvIXZBXcGZwZ+VYM8h8k9wuDvUODtdQ2Wcp2RcBkPTCSMmaniVHrMlA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8124,13 +8111,13 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.8.tgz", - "integrity": "sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.11.tgz", + "integrity": "sha512-fzbCh18rscBDTQSCrsp1fGcclLNF//nJyhjldsEl/5wCYmgpHblv5JSppQAyQI24lClsFT0wV06N1Porn0IsEw==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-serde-universal": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8138,13 +8125,13 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.8.tgz", - "integrity": "sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.11.tgz", + "integrity": "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-codec": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8152,14 +8139,15 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", - "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", + "version": "5.3.13", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.13.tgz", + "integrity": "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/querystring-builder": "^4.2.11", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -8167,14 +8155,14 @@ } }, "node_modules/@smithy/hash-blob-browser": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.9.tgz", - "integrity": "sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.12.tgz", + "integrity": "sha512-1wQE33DsxkM/waftAhCH9VtJbUGyt1PJ9YRDpOu+q9FUi73LLFUZ2fD8A61g2mT1UY9k7b99+V1xZ41Rz4SHRQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/chunked-blob-reader": "^5.2.0", - "@smithy/chunked-blob-reader-native": "^4.2.1", - "@smithy/types": "^4.12.0", + "@smithy/chunked-blob-reader": "^5.2.2", + "@smithy/chunked-blob-reader-native": "^4.2.3", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8182,13 +8170,14 @@ } }, "node_modules/@smithy/hash-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.8.tgz", - "integrity": "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.11.tgz", + "integrity": "sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8196,13 +8185,13 @@ } }, "node_modules/@smithy/hash-stream-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.8.tgz", - "integrity": "sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.11.tgz", + "integrity": "sha512-hQsTjwPCRY8w9GK07w1RqJi3e+myh0UaOWBBhZ1UMSDgofH/Q1fEYzU1teaX6HkpX/eWDdm7tAGR0jBPlz9QEQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8210,11 +8199,12 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.8.tgz", - "integrity": "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.11.tgz", + "integrity": "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8222,9 +8212,9 @@ } }, "node_modules/@smithy/is-array-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", - "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8234,13 +8224,13 @@ } }, "node_modules/@smithy/md5-js": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.8.tgz", - "integrity": "sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.11.tgz", + "integrity": "sha512-350X4kGIrty0Snx2OWv7rPM6p6vM7RzryvFs6B/56Cux3w3sChOb3bymo5oidXJlPcP9fIRxGUCk7GqpiSOtng==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8248,12 +8238,13 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.8.tgz", - "integrity": "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.11.tgz", + "integrity": "sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8261,17 +8252,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.4.14", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.14.tgz", - "integrity": "sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag==", + "version": "4.4.23", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.23.tgz", + "integrity": "sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.23.0", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-middleware": "^4.2.8", + "@smithy/core": "^3.23.9", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -8279,18 +8271,19 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.4.31", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.31.tgz", - "integrity": "sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg==", + "version": "4.4.40", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.40.tgz", + "integrity": "sha512-YhEMakG1Ae57FajERdHNZ4ShOPIY7DsgV+ZoAxo/5BT0KIe+f6DDU2rtIymNNFIj22NJfeeI6LWIifrwM0f+rA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/service-error-classification": "^4.2.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/uuid": "^1.1.0", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/service-error-classification": "^4.2.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" }, "engines": { @@ -8298,12 +8291,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", - "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.12.tgz", + "integrity": "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng==", + "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8311,11 +8305,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", - "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.11.tgz", + "integrity": "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8323,14 +8318,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", - "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.11.tgz", + "integrity": "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8338,14 +8333,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.10.tgz", - "integrity": "sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA==", + "version": "4.4.14", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.14.tgz", + "integrity": "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A==", + "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/abort-controller": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/querystring-builder": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8353,12 +8349,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", - "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.11.tgz", + "integrity": "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8366,12 +8362,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", - "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.11.tgz", + "integrity": "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8379,12 +8375,13 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", - "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.11.tgz", + "integrity": "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-uri-escape": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8392,11 +8389,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", - "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.11.tgz", + "integrity": "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8404,23 +8402,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", - "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.11.tgz", + "integrity": "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0" + "@smithy/types": "^4.13.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", - "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.6.tgz", + "integrity": "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8428,17 +8427,18 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.8.tgz", - "integrity": "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.11.tgz", + "integrity": "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-uri-escape": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8446,16 +8446,17 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.11.3.tgz", - "integrity": "sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.3.tgz", + "integrity": "sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.23.0", - "@smithy/middleware-endpoint": "^4.4.14", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.12", + "@smithy/core": "^3.23.9", + "@smithy/middleware-endpoint": "^4.4.23", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" }, "engines": { @@ -8475,12 +8476,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", - "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.11.tgz", + "integrity": "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing==", + "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/querystring-parser": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8488,13 +8490,13 @@ } }, "node_modules/@smithy/util-base64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", - "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8502,9 +8504,10 @@ } }, "node_modules/@smithy/util-body-length-browser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", - "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8513,9 +8516,10 @@ } }, "node_modules/@smithy/util-body-length-node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", - "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8524,12 +8528,12 @@ } }, "node_modules/@smithy/util-buffer-from": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", - "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", + "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8537,9 +8541,9 @@ } }, "node_modules/@smithy/util-config-provider": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", - "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8549,13 +8553,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.30", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.30.tgz", - "integrity": "sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng==", + "version": "4.3.39", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.39.tgz", + "integrity": "sha512-ui7/Ho/+VHqS7Km2wBw4/Ab4RktoiSshgcgpJzC4keFPs6tLJS4IQwbeahxQS3E/w98uq6E1mirCH/id9xIXeQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", + "@smithy/property-provider": "^4.2.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8563,16 +8568,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.33", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.33.tgz", - "integrity": "sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA==", + "version": "4.2.42", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.42.tgz", + "integrity": "sha512-QDA84CWNe8Akpj15ofLO+1N3Rfg8qa2K5uX0y6HnOp4AnRYRgWrKx/xzbYNbVF9ZsyJUYOfcoaN3y93wA/QJ2A==", + "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.4.6", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.11.3", - "@smithy/types": "^4.12.0", + "@smithy/config-resolver": "^4.4.10", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/smithy-client": "^4.12.3", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8580,12 +8586,13 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", - "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.2.tgz", + "integrity": "sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA==", + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8593,9 +8600,9 @@ } }, "node_modules/@smithy/util-hex-encoding": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", - "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -8605,11 +8612,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", - "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.11.tgz", + "integrity": "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8617,12 +8625,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", - "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.11.tgz", + "integrity": "sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw==", + "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/service-error-classification": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8630,17 +8639,18 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.5.12", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.12.tgz", - "integrity": "sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg==", + "version": "4.5.17", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.17.tgz", + "integrity": "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ==", + "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.10", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8648,9 +8658,10 @@ } }, "node_modules/@smithy/util-uri-escape": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", - "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8659,12 +8670,12 @@ } }, "node_modules/@smithy/util-utf8": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", - "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -8672,13 +8683,13 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.8.tgz", - "integrity": "sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.11.tgz", + "integrity": "sha512-x7Rh2azQPs3XxbvCzcttRErKKvLnbZfqRf/gOjw2pb+ZscX88e5UkRPCB67bVnsFHxayvMvmePfKTqsRb+is1A==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/abort-controller": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -8686,9 +8697,10 @@ } }, "node_modules/@smithy/uuid": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", - "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, @@ -8947,6 +8959,15 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@tabby_ai/hijri-converter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@tabby_ai/hijri-converter/-/hijri-converter-1.0.5.tgz", + "integrity": "sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@tailwindcss/forms": { "version": "0.5.11", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.11.tgz", @@ -9891,9 +9912,9 @@ "license": "MIT" }, "node_modules/@types/pg": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.16.0.tgz", - "integrity": "sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.18.0.tgz", + "integrity": "sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==", "devOptional": true, "license": "MIT", "dependencies": { @@ -11228,7 +11249,8 @@ "node_modules/bowser": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", - "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==" + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.12", @@ -14421,9 +14443,9 @@ } }, "node_modules/express-rate-limit": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.2.tgz", - "integrity": "sha512-Ybv7bqtOgA914MLwaHWVFXMpMYeR1MQu/D+z2MaLYteqBsTIp9sY3AU7mGNLMJv8eLg8uQMpE20I+L2Lv49nSg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.0.tgz", + "integrity": "sha512-KJzBawY6fB9FiZGdE/0aftepZ91YlaGIrV8vgblRM3J8X+dHx/aiowJWwkx6LIGyuqGiANsjSwwrbb8mifOJ4Q==", "license": "MIT", "dependencies": { "ip-address": "10.1.0" @@ -15509,11 +15531,12 @@ } }, "node_modules/ioredis": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.9.3.tgz", - "integrity": "sha512-VI5tMCdeoxZWU5vjHWsiE/Su76JGhBvWF1MJnV9ZtGltHk9BmD48oDq8Tj8haZ85aceXZMxLNDQZRVo5QKNgXA==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.10.0.tgz", + "integrity": "sha512-HVBe9OFuqs+Z6n64q09PQvP1/R4Bm+30PAyyD4wIEqssh3v9L21QjCVk4kRLucMBcDokJTcLjsGeVRlq/nH6DA==", + "license": "MIT", "dependencies": { - "@ioredis/commands": "1.5.0", + "@ioredis/commands": "1.5.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", @@ -16638,9 +16661,9 @@ } }, "node_modules/lucide-react": { - "version": "0.563.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.563.0.tgz", - "integrity": "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA==", + "version": "0.577.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", + "integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -17936,14 +17959,14 @@ } }, "node_modules/pg": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.19.0.tgz", - "integrity": "sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", "license": "MIT", "dependencies": { - "pg-connection-string": "^2.11.0", - "pg-pool": "^3.12.0", - "pg-protocol": "^1.12.0", + "pg-connection-string": "^2.12.0", + "pg-pool": "^3.13.0", + "pg-protocol": "^1.13.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, @@ -17970,9 +17993,9 @@ "optional": true }, "node_modules/pg-connection-string": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", - "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", + "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", "license": "MIT" }, "node_modules/pg-int8": { @@ -17985,18 +18008,18 @@ } }, "node_modules/pg-pool": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.12.0.tgz", - "integrity": "sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", + "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.12.0.tgz", - "integrity": "sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", "license": "MIT" }, "node_modules/pg-types": { @@ -18158,15 +18181,23 @@ } }, "node_modules/posthog-node": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.26.0.tgz", - "integrity": "sha512-DK1XF/RiunhvT57cFyPxW9OaliZzl5aREHFwY/AISL3MVOaDUb4wIccMn0G3ws3Ounen8iGH7xvzZQ0x2vEOEQ==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.28.0.tgz", + "integrity": "sha512-EETYV0zA+7BLQmXzY+vGyDMoQK8uHf8f/1utbRjKncI41gPkw+4piGP7l4UT5Luld+4vQpJPOR1q1YrbXm7XjQ==", "license": "MIT", "dependencies": { - "@posthog/core": "1.23.1" + "@posthog/core": "1.23.2" }, "engines": { "node": "^20.20.0 || >=22.22.0" + }, + "peerDependencies": { + "rxjs": "^7.0.0" + }, + "peerDependenciesMeta": { + "rxjs": { + "optional": true + } } }, "node_modules/prebuild-install": { @@ -18440,13 +18471,15 @@ } }, "node_modules/react-day-picker": { - "version": "9.13.2", - "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.13.2.tgz", - "integrity": "sha512-IMPiXfXVIAuR5Yk58DDPBC8QKClrhdXV+Tr/alBrwrHUw0qDDYB1m5zPNuTnnPIr/gmJ4ChMxmtqPdxm8+R4Eg==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.14.0.tgz", + "integrity": "sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==", + "license": "MIT", "dependencies": { "@date-fns/tz": "^1.4.1", + "@tabby_ai/hijri-converter": "1.0.5", "date-fns": "^4.1.0", - "date-fns-jalali": "^4.1.0-0" + "date-fns-jalali": "4.1.0-0" }, "engines": { "node": ">=18" @@ -19315,9 +19348,9 @@ } }, "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz", + "integrity": "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==", "license": "MIT", "peerDependencies": { "react": "*" @@ -19566,11 +19599,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/reo-census": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/reo-census/-/reo-census-1.2.8.tgz", + "integrity": "sha512-UMwpNwOieUTeymIITWCbo0In0FHGWZwnXIIYphpCPO/Bjl5z/385DWLnTxBcfFFCH/r/fEq/TZ0ivlPb6Smi9Q==", + "hasInstallScript": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/reodotdev": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/reodotdev/-/reodotdev-1.0.0.tgz", - "integrity": "sha512-wXe1vJucZjrhQL0SxOL9EvmJrtbMCIEGMdZX5lj/57n2T3UhBHZsAcM5TQASJ0T6ZBbrETRnMhH33bsbJeRO6Q==", - "license": "MIT" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reodotdev/-/reodotdev-1.1.0.tgz", + "integrity": "sha512-BeIlYk59p4Gw+zPHJj249xPBQ0wHfI8NsksVFRTdPLkPXDSYyn6IBvbR0s7pELK9qk3p79UBcBWP84IsYLsvbg==", + "license": "MIT", + "dependencies": { + "reo-census": "^1.2.6" + } }, "node_modules/require-from-string": { "version": "2.0.2", @@ -20599,9 +20645,9 @@ } }, "node_modules/stripe": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-20.3.1.tgz", - "integrity": "sha512-k990yOT5G5rhX3XluRPw5Y8RLdJDW4dzQ29wWT66piHrbnM2KyamJ1dKgPsw4HzGHRWjDiSSdcI2WdxQUPV3aQ==", + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-20.4.1.tgz", + "integrity": "sha512-axCguHItc8Sxt0HC6aSkdVRPffjYPV7EQqZRb2GkIa8FzWDycE7nHJM19C6xAIynH1Qp1/BHiopSi96jGBxT0w==", "license": "MIT", "engines": { "node": ">=16" diff --git a/package.json b/package.json index f0bb0b9b4..ec8e99cce 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "dependencies": { "@asteasolutions/zod-to-openapi": "8.4.1", - "@aws-sdk/client-s3": "3.989.0", + "@aws-sdk/client-s3": "3.1004.0", "@faker-js/faker": "10.3.0", "@headlessui/react": "2.2.9", "@hookform/resolvers": "5.2.2", @@ -80,16 +80,16 @@ "d3": "7.9.0", "drizzle-orm": "0.45.1", "express": "5.2.1", - "express-rate-limit": "8.2.2", + "express-rate-limit": "8.3.0", "glob": "13.0.6", "helmet": "8.1.0", "http-errors": "2.0.1", "input-otp": "1.4.2", - "ioredis": "5.9.3", + "ioredis": "5.10.0", "jmespath": "0.16.0", "js-yaml": "4.1.1", "jsonwebtoken": "9.0.3", - "lucide-react": "0.563.0", + "lucide-react": "0.577.0", "maxmind": "5.0.5", "moment": "2.30.1", "next": "15.5.12", @@ -99,21 +99,21 @@ "node-cache": "5.1.2", "nodemailer": "8.0.1", "oslo": "1.2.1", - "pg": "8.19.0", - "posthog-node": "5.26.0", + "pg": "8.20.0", + "posthog-node": "5.28.0", "qrcode.react": "4.2.0", "react": "19.2.4", - "react-day-picker": "9.13.2", + "react-day-picker": "9.14.0", "react-dom": "19.2.4", "react-easy-sort": "1.8.0", "react-hook-form": "7.71.2", - "react-icons": "5.5.0", + "react-icons": "5.6.0", "recharts": "2.15.4", - "reodotdev": "1.0.0", + "reodotdev": "1.1.0", "resend": "6.9.2", "semver": "7.7.4", "sshpk": "^1.18.0", - "stripe": "20.3.1", + "stripe": "20.4.1", "swagger-ui-express": "5.0.1", "tailwind-merge": "3.5.0", "topojson-client": "3.1.0", @@ -149,7 +149,7 @@ "@types/node": "25.3.5", "@types/nodemailer": "7.0.11", "@types/nprogress": "0.2.3", - "@types/pg": "8.16.0", + "@types/pg": "8.18.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@types/semver": "7.7.1", From dbdff6812deed65693d3df14f55f32c6a345e788 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:31:19 -0700 Subject: [PATCH 21/50] Bump esbuild --- package-lock.json | 1864 --------------------------------------------- package.json | 3 + 2 files changed, 3 insertions(+), 1864 deletions(-) diff --git a/package-lock.json b/package-lock.json index b48f368ac..84bfc70a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1542,418 +1542,6 @@ "source-map-support": "^0.5.21" } }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, "node_modules/@esbuild-kit/esm-loader": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", @@ -7096,448 +6684,6 @@ "next": "16.1.6" } }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-loong64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-s390x": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/sunos-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@react-email/preview-server/node_modules/@next/env": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.6.tgz", @@ -7691,48 +6837,6 @@ "tslib": "^2.8.0" } }, - "node_modules/@react-email/preview-server/node_modules/esbuild": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.10", - "@esbuild/android-arm": "0.25.10", - "@esbuild/android-arm64": "0.25.10", - "@esbuild/android-x64": "0.25.10", - "@esbuild/darwin-arm64": "0.25.10", - "@esbuild/darwin-x64": "0.25.10", - "@esbuild/freebsd-arm64": "0.25.10", - "@esbuild/freebsd-x64": "0.25.10", - "@esbuild/linux-arm": "0.25.10", - "@esbuild/linux-arm64": "0.25.10", - "@esbuild/linux-ia32": "0.25.10", - "@esbuild/linux-loong64": "0.25.10", - "@esbuild/linux-mips64el": "0.25.10", - "@esbuild/linux-ppc64": "0.25.10", - "@esbuild/linux-riscv64": "0.25.10", - "@esbuild/linux-s390x": "0.25.10", - "@esbuild/linux-x64": "0.25.10", - "@esbuild/netbsd-arm64": "0.25.10", - "@esbuild/netbsd-x64": "0.25.10", - "@esbuild/openbsd-arm64": "0.25.10", - "@esbuild/openbsd-x64": "0.25.10", - "@esbuild/openharmony-arm64": "0.25.10", - "@esbuild/sunos-x64": "0.25.10", - "@esbuild/win32-arm64": "0.25.10", - "@esbuild/win32-ia32": "0.25.10", - "@esbuild/win32-x64": "0.25.10" - } - }, "node_modules/@react-email/preview-server/node_modules/next": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/next/-/next-16.1.6.tgz", @@ -12729,490 +11833,6 @@ "drizzle-kit": "bin.cjs" } }, - "node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/drizzle-orm": { "version": "0.45.1", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.1.tgz", @@ -18501,448 +17121,6 @@ "node": ">=20.0.0" } }, - "node_modules/react-email/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/react-email/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -19012,48 +17190,6 @@ "dev": true, "license": "MIT" }, - "node_modules/react-email/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/react-email/node_modules/glob": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", diff --git a/package.json b/package.json index 56caec09a..9be5dd261 100644 --- a/package.json +++ b/package.json @@ -171,5 +171,8 @@ "tsx": "4.21.0", "typescript": "5.9.3", "typescript-eslint": "8.55.0" + }, + "overrides": { + "esbuild": "0.27.3" } } From 072c89e704841fca9e266bfb43426b3fff277f79 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:43:40 -0700 Subject: [PATCH 22/50] Bump dompurify --- package-lock.json | 9 ++++++--- package.json | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 84bfc70a0..cc8adc58b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11767,10 +11767,13 @@ } }, "node_modules/dompurify": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", - "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", + "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", "license": "(MPL-2.0 OR Apache-2.0)", + "engines": { + "node": ">=20" + }, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } diff --git a/package.json b/package.json index 9be5dd261..9eec59b43 100644 --- a/package.json +++ b/package.json @@ -173,6 +173,7 @@ "typescript-eslint": "8.55.0" }, "overrides": { - "esbuild": "0.27.3" + "esbuild": "0.27.3", + "dompurify": "3.3.2" } } From 5c50590d7b3a097e523fb8553c06b36e8d02296e Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:31:19 -0700 Subject: [PATCH 23/50] Bump esbuild --- package-lock.json | 1864 --------------------------------------------- package.json | 3 + 2 files changed, 3 insertions(+), 1864 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e3b0e759..bcf0f55d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1526,418 +1526,6 @@ "source-map-support": "^0.5.21" } }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, "node_modules/@esbuild-kit/esm-loader": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", @@ -7057,448 +6645,6 @@ "next": "16.1.6" } }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/android-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/darwin-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-loong64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-s390x": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/linux-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/sunos-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@react-email/preview-server/node_modules/@esbuild/win32-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@react-email/preview-server/node_modules/@next/env": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.6.tgz", @@ -7652,48 +6798,6 @@ "tslib": "^2.8.0" } }, - "node_modules/@react-email/preview-server/node_modules/esbuild": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.10", - "@esbuild/android-arm": "0.25.10", - "@esbuild/android-arm64": "0.25.10", - "@esbuild/android-x64": "0.25.10", - "@esbuild/darwin-arm64": "0.25.10", - "@esbuild/darwin-x64": "0.25.10", - "@esbuild/freebsd-arm64": "0.25.10", - "@esbuild/freebsd-x64": "0.25.10", - "@esbuild/linux-arm": "0.25.10", - "@esbuild/linux-arm64": "0.25.10", - "@esbuild/linux-ia32": "0.25.10", - "@esbuild/linux-loong64": "0.25.10", - "@esbuild/linux-mips64el": "0.25.10", - "@esbuild/linux-ppc64": "0.25.10", - "@esbuild/linux-riscv64": "0.25.10", - "@esbuild/linux-s390x": "0.25.10", - "@esbuild/linux-x64": "0.25.10", - "@esbuild/netbsd-arm64": "0.25.10", - "@esbuild/netbsd-x64": "0.25.10", - "@esbuild/openbsd-arm64": "0.25.10", - "@esbuild/openbsd-x64": "0.25.10", - "@esbuild/openharmony-arm64": "0.25.10", - "@esbuild/sunos-x64": "0.25.10", - "@esbuild/win32-arm64": "0.25.10", - "@esbuild/win32-ia32": "0.25.10", - "@esbuild/win32-x64": "0.25.10" - } - }, "node_modules/@react-email/preview-server/node_modules/next": { "version": "16.1.6", "resolved": "https://registry.npmjs.org/next/-/next-16.1.6.tgz", @@ -12751,490 +11855,6 @@ "drizzle-kit": "bin.cjs" } }, - "node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/drizzle-kit/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/drizzle-orm": { "version": "0.45.1", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.1.tgz", @@ -18552,448 +17172,6 @@ "node": ">=20.0.0" } }, - "node_modules/react-email/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/react-email/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/react-email/node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -19063,48 +17241,6 @@ "dev": true, "license": "MIT" }, - "node_modules/react-email/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/react-email/node_modules/glob": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", diff --git a/package.json b/package.json index ec8e99cce..5906f363c 100644 --- a/package.json +++ b/package.json @@ -172,5 +172,8 @@ "tsx": "4.21.0", "typescript": "5.9.3", "typescript-eslint": "8.56.1" + }, + "overrides": { + "esbuild": "0.27.3" } } From 99e6bd31b6f35f6142ff834e9b4692303b96a8f0 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 16:43:40 -0700 Subject: [PATCH 24/50] Bump dompurify --- package-lock.json | 68 ++++++++++++++++++++++++++++++++++++++++------- package.json | 3 ++- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index bcf0f55d4..03ff44d30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1071,6 +1071,7 @@ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -2381,6 +2382,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2403,6 +2405,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2425,6 +2428,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2441,6 +2445,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2457,6 +2462,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2473,6 +2479,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2489,6 +2496,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2505,6 +2513,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2521,6 +2530,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2537,6 +2547,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2553,6 +2564,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2569,6 +2581,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2591,6 +2604,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2613,6 +2627,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2635,6 +2650,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2657,6 +2673,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2679,6 +2696,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2701,6 +2719,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -2723,6 +2742,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -2742,6 +2762,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -2761,6 +2782,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -2780,6 +2802,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -3039,6 +3062,7 @@ "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^14.21.3 || >=16" }, @@ -6985,6 +7009,7 @@ "resolved": "https://registry.npmjs.org/@react-email/text/-/text-0.1.6.tgz", "integrity": "sha512-TYqkioRS45wTR5il3dYk/SbUjjEdhSwh9BtRNB99qNH1pXAwA45H7rAuxehiu8iJQJH0IyIr+6n62gBz9ezmsw==", "license": "MIT", + "peer": true, "engines": { "node": ">=20.0.0" }, @@ -8444,6 +8469,7 @@ "version": "5.90.21", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", + "peer": true, "dependencies": { "@tanstack/query-core": "5.90.20" }, @@ -8559,6 +8585,7 @@ "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -8899,6 +8926,7 @@ "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", @@ -8994,6 +9022,7 @@ "integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -9021,6 +9050,7 @@ "integrity": "sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -9046,6 +9076,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -9056,6 +9087,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -9142,8 +9174,7 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/@types/ws": { "version": "8.18.1", @@ -9217,6 +9248,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", @@ -9742,6 +9774,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -10206,6 +10239,7 @@ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/types": "^7.26.0" } @@ -10272,6 +10306,7 @@ "integrity": "sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==", "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" @@ -10399,6 +10434,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -11352,6 +11388,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -11788,11 +11825,13 @@ } }, "node_modules/dompurify": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", - "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", + "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", "license": "(MPL-2.0 OR Apache-2.0)", - "peer": true, + "engines": { + "node": ">=20" + }, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -12422,6 +12461,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -12520,6 +12560,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -12705,6 +12746,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -13024,6 +13066,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -15550,7 +15593,6 @@ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", "license": "MIT", - "peer": true, "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" @@ -15561,7 +15603,6 @@ "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -15649,6 +15690,7 @@ "version": "15.5.12", "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz", "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==", + "peer": true, "dependencies": { "@next/env": "15.5.12", "@swc/helpers": "0.5.15", @@ -16583,6 +16625,7 @@ "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", "license": "MIT", + "peer": true, "dependencies": { "pg-connection-string": "^2.12.0", "pg-pool": "^3.13.0", @@ -17086,6 +17129,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" } @@ -17117,6 +17161,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -17472,6 +17517,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.2.tgz", "integrity": "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -18955,7 +19001,8 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tapable": { "version": "2.3.0", @@ -19430,6 +19477,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -19857,6 +19905,7 @@ "resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz", "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", "license": "MIT", + "peer": true, "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.8", @@ -20063,6 +20112,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 5906f363c..3529de66a 100644 --- a/package.json +++ b/package.json @@ -174,6 +174,7 @@ "typescript-eslint": "8.56.1" }, "overrides": { - "esbuild": "0.27.3" + "esbuild": "0.27.3", + "dompurify": "3.3.2" } } From 82f88f2cd3a9a56e2b544aa8d28bade74c761cd0 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 20:46:27 -0700 Subject: [PATCH 25/50] Reorder delete --- server/lib/deleteOrg.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index cca2ea974..86c32e9a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -121,6 +121,9 @@ export async function deleteOrgById( eq(clientSitesAssociationsCache.clientId, client.clientId) ); } + + await trx.delete(resources).where(eq(resources.orgId, orgId)); + const allOrgDomains = await trx .select() .from(orgDomains) @@ -147,7 +150,6 @@ export async function deleteOrgById( .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); } - await trx.delete(resources).where(eq(resources.orgId, orgId)); await usageService.add(orgId, FeatureId.ORGINIZATIONS, -1, trx); // here we are decreasing the org count BEFORE deleting the org because we need to still be able to get the org to get the billing org inside of here From 225591094f437625e21884b452653efc3033eaea Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 21:16:37 -0700 Subject: [PATCH 26/50] Clean up --- server/lib/deleteOrg.ts | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 86c32e9a1..56f2848a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -85,9 +85,7 @@ export async function deleteOrgById( deletedNewtIds.push(deletedNewt.newtId); await trx .delete(newtSessions) - .where( - eq(newtSessions.newtId, deletedNewt.newtId) - ); + .where(eq(newtSessions.newtId, deletedNewt.newtId)); } } } @@ -127,7 +125,7 @@ export async function deleteOrgById( const allOrgDomains = await trx .select() .from(orgDomains) - .innerJoin(domains, eq(domains.domainId, orgDomains.domainId)) + .innerJoin(domains, eq(orgDomains.domainId, domains.domainId)) .where( and( eq(orgDomains.orgId, orgId), @@ -136,16 +134,17 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domains.domainId; + const domainId = orgDomain.domainId; const orgCount = await trx - .select({ count: sql`count(*)` }) + .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count === 1) { + if (orgCount[0].count == 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { + // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); @@ -233,15 +232,13 @@ export function sendTerminationMessages(result: DeleteOrgByIdResult): void { ); } for (const olmId of result.olmsToTerminate) { - sendTerminateClient( - 0, - OlmErrorCodes.TERMINATED_REKEYED, - olmId - ).catch((error) => { - logger.error( - "Failed to send termination message to olm:", - error - ); - }); + sendTerminateClient(0, OlmErrorCodes.TERMINATED_REKEYED, olmId).catch( + (error) => { + logger.error( + "Failed to send termination message to olm:", + error + ); + } + ); } } From 4975cabb2c35fd9dc74786262f2a914d89b593d3 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 10:03:49 -0700 Subject: [PATCH 27/50] Use native drizzle count --- server/lib/deleteOrg.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index 56f2848a1..b32667d24 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -134,17 +134,16 @@ export async function deleteOrgById( ); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { - const domainId = orgDomain.domainId; - const orgCount = await trx + const domainId = orgDomain.domains.domainId; + const [orgCount] = await trx .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); - if (orgCount[0].count == 1) { + if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } if (domainIdsToDelete.length > 0) { - // delete the orgDomain await trx .delete(domains) .where(inArray(domains.domainId, domainIdsToDelete)); From 4e2d88efdd37c3fc3670135b08c513c01629c203 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 10 Mar 2026 14:24:57 -0700 Subject: [PATCH 28/50] Add some logging to debug --- server/lib/deleteOrg.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/lib/deleteOrg.ts b/server/lib/deleteOrg.ts index b32667d24..065f216a1 100644 --- a/server/lib/deleteOrg.ts +++ b/server/lib/deleteOrg.ts @@ -132,6 +132,7 @@ export async function deleteOrgById( eq(domains.configManaged, false) ) ); + logger.info(`Found ${allOrgDomains.length} domains to delete`); const domainIdsToDelete: string[] = []; for (const orgDomain of allOrgDomains) { const domainId = orgDomain.domains.domainId; @@ -139,10 +140,12 @@ export async function deleteOrgById( .select({ count: count() }) .from(orgDomains) .where(eq(orgDomains.domainId, domainId)); + logger.info(`Found ${orgCount.count} orgs using domain ${domainId}`); if (orgCount.count === 1) { domainIdsToDelete.push(domainId); } } + logger.info(`Found ${domainIdsToDelete.length} domains to delete`); if (domainIdsToDelete.length > 0) { await trx .delete(domains) From 1cc5f59f66d3b14dcef455a024fabe510468308b Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 11:37:27 -0700 Subject: [PATCH 29/50] Implement email and ip banning --- server/db/pg/schema/privateSchema.ts | 8 ++++++++ server/db/sqlite/schema/privateSchema.ts | 9 ++++++++ server/routers/auth/signup.ts | 26 +++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/server/db/pg/schema/privateSchema.ts b/server/db/pg/schema/privateSchema.ts index 6ff542de2..c9d7cc907 100644 --- a/server/db/pg/schema/privateSchema.ts +++ b/server/db/pg/schema/privateSchema.ts @@ -328,6 +328,14 @@ export const approvals = pgTable("approvals", { .notNull() }); +export const bannedEmails = pgTable("bannedEmails", { + email: varchar("email", { length: 255 }).primaryKey(), +}); + +export const bannedIps = pgTable("bannedIps", { + ip: varchar("ip", { length: 255 }).primaryKey(), +}); + export type Approval = InferSelectModel; export type Limit = InferSelectModel; export type Account = InferSelectModel; diff --git a/server/db/sqlite/schema/privateSchema.ts b/server/db/sqlite/schema/privateSchema.ts index 40f6d7134..8baeb5220 100644 --- a/server/db/sqlite/schema/privateSchema.ts +++ b/server/db/sqlite/schema/privateSchema.ts @@ -318,6 +318,15 @@ export const approvals = sqliteTable("approvals", { .notNull() }); + +export const bannedEmails = sqliteTable("bannedEmails", { + email: text("email").primaryKey() +}); + +export const bannedIps = sqliteTable("bannedIps", { + ip: text("ip").primaryKey() +}); + export type Approval = InferSelectModel; export type Limit = InferSelectModel; export type Account = InferSelectModel; diff --git a/server/routers/auth/signup.ts b/server/routers/auth/signup.ts index 93403a503..171653789 100644 --- a/server/routers/auth/signup.ts +++ b/server/routers/auth/signup.ts @@ -1,5 +1,5 @@ import { NextFunction, Request, Response } from "express"; -import { db, users } from "@server/db"; +import { bannedEmails, bannedIps, db, users } from "@server/db"; import HttpCode from "@server/types/HttpCode"; import { email, z } from "zod"; import { fromError } from "zod-validation-error"; @@ -66,6 +66,30 @@ export async function signup( skipVerificationEmail } = parsedBody.data; + const [bannedEmail] = await db + .select() + .from(bannedEmails) + .where(eq(bannedEmails.email, email)) + .limit(1); + if (bannedEmail) { + return next( + createHttpError(HttpCode.FORBIDDEN, "Signup blocked. Do not attempt to continue to use this service.") + ); + } + + if (req.ip) { + const [bannedIp] = await db + .select() + .from(bannedIps) + .where(eq(bannedIps.ip, req.ip)) + .limit(1); + if (bannedIp) { + return next( + createHttpError(HttpCode.FORBIDDEN, "Signup blocked. Do not attempt to continue to use this service.") + ); + } + } + const passwordHash = await hashPassword(password); const userId = generateId(15); From 82c9a1eb701a90c31cb0d155e3b4073197b14e75 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:04 -0700 Subject: [PATCH 30/50] Add demo link --- messages/en-US.json | 4 ++-- src/components/PaidFeaturesAlert.tsx | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index d84f4f337..6a35d79bb 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -2343,8 +2343,8 @@ "logRetentionEndOfFollowingYear": "End of following year", "actionLogsDescription": "View a history of actions performed in this organization", "accessLogsDescription": "View access auth requests for resources in this organization", - "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature.", - "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud.", + "licenseRequiredToUse": "An Enterprise Edition license or Pangolin Cloud is required to use this feature. Book a demo or POC trial.", + "ossEnterpriseEditionRequired": "The Enterprise Edition is required to use this feature. This feature is also available in Pangolin Cloud. Book a demo or POC trial.", "certResolver": "Certificate Resolver", "certResolverDescription": "Select the certificate resolver to use for this resource.", "selectCertResolver": "Select Certificate Resolver", diff --git a/src/components/PaidFeaturesAlert.tsx b/src/components/PaidFeaturesAlert.tsx index adbb49d9e..95179ea78 100644 --- a/src/components/PaidFeaturesAlert.tsx +++ b/src/components/PaidFeaturesAlert.tsx @@ -51,6 +51,7 @@ const docsLinkClassName = const PANGOLIN_CLOUD_SIGNUP_URL = "https://app.pangolin.net/auth/signup/"; const ENTERPRISE_DOCS_URL = "https://docs.pangolin.net/self-host/enterprise-edition"; +const BOOK_A_DEMO_URL = "https://click.fossorial.io/ep922"; function getTierLinkRenderer(billingHref: string) { return function tierLinkRenderer(chunks: React.ReactNode) { @@ -78,6 +79,22 @@ function getPangolinCloudLinkRenderer() { }; } +function getBookADemoLinkRenderer() { + return function bookADemoLinkRenderer(chunks: React.ReactNode) { + return ( + + {chunks} + + + ); + }; +} + function getDocsLinkRenderer(href: string) { return function docsLinkRenderer(chunks: React.ReactNode) { return ( @@ -116,6 +133,7 @@ export function PaidFeaturesAlert({ tiers }: Props) { const tierLinkRenderer = getTierLinkRenderer(billingHref); const pangolinCloudLinkRenderer = getPangolinCloudLinkRenderer(); const enterpriseDocsLinkRenderer = getDocsLinkRenderer(ENTERPRISE_DOCS_URL); + const bookADemoLinkRenderer = getBookADemoLinkRenderer(); if (env.flags.disableEnterpriseFeatures) { return null; @@ -157,7 +175,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("licenseRequiredToUse", { enterpriseLicenseLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })} @@ -174,7 +193,8 @@ export function PaidFeaturesAlert({ tiers }: Props) { {t.rich("ossEnterpriseEditionRequired", { enterpriseEditionLink: enterpriseDocsLinkRenderer, - pangolinCloudLink: pangolinCloudLinkRenderer + pangolinCloudLink: pangolinCloudLinkRenderer, + bookADemoLink: bookADemoLinkRenderer })} From eda43dffe14e831301e61d435b8ebacc88b04428 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:34:48 -0700 Subject: [PATCH 31/50] Fix not pulling wildcard cert updates --- server/lib/traefik/TraefikConfigManager.ts | 89 +++++++++++++++++++--- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/server/lib/traefik/TraefikConfigManager.ts b/server/lib/traefik/TraefikConfigManager.ts index 46d5ccc85..de9249291 100644 --- a/server/lib/traefik/TraefikConfigManager.ts +++ b/server/lib/traefik/TraefikConfigManager.ts @@ -218,10 +218,11 @@ export class TraefikConfigManager { return true; } - // Fetch if it's been more than 24 hours (for renewals) const dayInMs = 24 * 60 * 60 * 1000; const timeSinceLastFetch = Date.now() - this.lastCertificateFetch.getTime(); + + // Fetch if it's been more than 24 hours (daily routine check) if (timeSinceLastFetch > dayInMs) { logger.info("Fetching certificates due to 24-hour renewal check"); return true; @@ -265,7 +266,7 @@ export class TraefikConfigManager { return true; } - // Check if any local certificates are missing or appear to be outdated + // Check if any local certificates are missing (needs immediate fetch) for (const domain of domainsNeedingCerts) { const localState = this.lastLocalCertificateState.get(domain); if (!localState || !localState.exists) { @@ -274,17 +275,55 @@ export class TraefikConfigManager { ); return true; } + } - // Check if certificate is expiring soon (within 30 days) - if (localState.expiresAt) { - const nowInSeconds = Math.floor(Date.now() / 1000); - const secondsUntilExpiry = localState.expiresAt - nowInSeconds; - const daysUntilExpiry = secondsUntilExpiry / (60 * 60 * 24); - if (daysUntilExpiry < 30) { - logger.info( - `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` - ); - return true; + // For expiry checks, throttle to every 6 hours to avoid querying the + // API/DB on every monitor loop. The certificate-service renews certs + // 45 days before expiry, so checking every 6 hours is plenty frequent + // to pick up renewed certs promptly. + const renewalCheckIntervalMs = 6 * 60 * 60 * 1000; // 6 hours + if (timeSinceLastFetch > renewalCheckIntervalMs) { + // Check non-wildcard certs for expiry (within 45 days to match + // the server-side renewal window in certificate-service) + for (const domain of domainsNeedingCerts) { + const localState = + this.lastLocalCertificateState.get(domain); + if (localState?.expiresAt) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + localState.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for ${domain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } + } + } + + // Also check wildcard certificates for expiry. These are not + // included in domainsNeedingCerts since their subdomains are + // filtered out, so we must check them separately. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor(Date.now() / 1000); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + logger.info( + `Fetching certificates due to upcoming expiry for wildcard cert ${certDomain} (${Math.round(daysUntilExpiry)} days remaining)` + ); + return true; + } } } } @@ -361,6 +400,32 @@ export class TraefikConfigManager { } } + // Also include wildcard cert base domains that are + // expiring or expired so they get re-fetched even though + // their subdomains were filtered out above. + for (const [certDomain, state] of this + .lastLocalCertificateState) { + if ( + state.exists && + state.wildcard && + state.expiresAt + ) { + const nowInSeconds = Math.floor( + Date.now() / 1000 + ); + const secondsUntilExpiry = + state.expiresAt - nowInSeconds; + const daysUntilExpiry = + secondsUntilExpiry / (60 * 60 * 24); + if (daysUntilExpiry < 45) { + domainsToFetch.add(certDomain); + logger.info( + `Including expiring wildcard cert domain ${certDomain} in fetch (${Math.round(daysUntilExpiry)} days remaining)` + ); + } + } + } + if (domainsToFetch.size > 0) { // Get valid certificates for domains not covered by wildcards validCertificates = From b24de85157c87c20c9bc31fb86dae525fc787e23 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 9 Mar 2026 17:35:16 -0700 Subject: [PATCH 32/50] Handle gerbil rejecting 0 Closes #2605 --- server/lib/rebuildClientAssociations.ts | 4 ++-- server/routers/gerbil/getAllRelays.ts | 4 ++-- server/routers/gerbil/updateHolePunch.ts | 2 +- server/routers/newt/handleGetConfigMessage.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/lib/rebuildClientAssociations.ts b/server/lib/rebuildClientAssociations.ts index 625e57935..af43a6d00 100644 --- a/server/lib/rebuildClientAssociations.ts +++ b/server/lib/rebuildClientAssociations.ts @@ -571,7 +571,7 @@ export async function updateClientSiteDestinations( destinations: [ { destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } ] }; @@ -579,7 +579,7 @@ export async function updateClientSiteDestinations( // add to the existing destinations destinations.destinations.push({ destinationIP: site.sites.subnet.split("/")[0], - destinationPort: site.sites.listenPort || 0 + destinationPort: site.sites.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } diff --git a/server/routers/gerbil/getAllRelays.ts b/server/routers/gerbil/getAllRelays.ts index b7d33b955..bbe314b2a 100644 --- a/server/routers/gerbil/getAllRelays.ts +++ b/server/routers/gerbil/getAllRelays.ts @@ -125,7 +125,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { // Add site as a destination for this client const destination: PeerDestination = { destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check if this destination is already in the array to avoid duplicates @@ -165,7 +165,7 @@ export async function generateRelayMappings(exitNode: ExitNode) { const destination: PeerDestination = { destinationIP: peer.subnet.split("/")[0], - destinationPort: peer.listenPort + destinationPort: peer.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }; // Check for duplicates diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 3f24430bf..13d0ed276 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -262,7 +262,7 @@ export async function updateAndGenerateEndpointDestinations( if (site.subnet && site.listenPort) { destinations.push({ destinationIP: site.subnet.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }); } } diff --git a/server/routers/newt/handleGetConfigMessage.ts b/server/routers/newt/handleGetConfigMessage.ts index 801c8b65a..24cca17a2 100644 --- a/server/routers/newt/handleGetConfigMessage.ts +++ b/server/routers/newt/handleGetConfigMessage.ts @@ -104,11 +104,11 @@ export const handleGetConfigMessage: MessageHandler = async (context) => { const payload = { oldDestination: { destinationIP: existingSite.subnet?.split("/")[0], - destinationPort: existingSite.listenPort + destinationPort: existingSite.listenPort || 1 // this satisfies gerbil for now but should be reevaluated }, newDestination: { destinationIP: site.subnet?.split("/")[0], - destinationPort: site.listenPort + destinationPort: site.listenPort || 1 // this satisfies gerbil for now but should be reevaluated } }; From 90afe5a7acb32c8bf7f68335bc309615670cad37 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 15:41:57 -0700 Subject: [PATCH 33/50] Log errors --- server/routers/gerbil/updateHolePunch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 13d0ed276..3eacc1da1 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -112,7 +112,7 @@ export async function updateHolePunch( destinations: destinations }); } catch (error) { - // logger.error(error); // FIX THIS + logger.error(error); return next( createHttpError( HttpCode.INTERNAL_SERVER_ERROR, From 9b0e7b381c753c235ae5a035bc98de497af53194 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 15:48:20 -0700 Subject: [PATCH 34/50] Fix error to gerbil --- server/routers/gerbil/updateHolePunch.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index 3eacc1da1..810c44ff7 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -339,10 +339,10 @@ export async function updateAndGenerateEndpointDestinations( handleSiteEndpointChange(newt.siteId, updatedSite.endpoint!); } - if (!updatedSite || !updatedSite.subnet) { - logger.warn(`Site not found: ${newt.siteId}`); - throw new Error("Site not found"); - } + // if (!updatedSite || !updatedSite.subnet) { + // logger.warn(`Site not found: ${newt.siteId}`); + // throw new Error("Site not found"); + // } // Find all clients that connect to this site // const sitesClientPairs = await db From 74f4751bcc8b897f4a4d6027a3f0dd55f87b5670 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 17:47:15 -0700 Subject: [PATCH 35/50] Dont show raw resource option unless remote node --- .../settings/resources/proxy/create/page.tsx | 110 ++++++++++++------ 1 file changed, 76 insertions(+), 34 deletions(-) diff --git a/src/app/[orgId]/settings/resources/proxy/create/page.tsx b/src/app/[orgId]/settings/resources/proxy/create/page.tsx index 127917555..4c8cb8443 100644 --- a/src/app/[orgId]/settings/resources/proxy/create/page.tsx +++ b/src/app/[orgId]/settings/resources/proxy/create/page.tsx @@ -54,6 +54,7 @@ import { TooltipProvider, TooltipTrigger } from "@app/components/ui/tooltip"; +import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { toast } from "@app/hooks/useToast"; import { createApiClient, formatAxiosError } from "@app/lib/api"; @@ -65,6 +66,7 @@ import { build } from "@server/build"; import { Resource } from "@server/db"; import { isTargetValid } from "@server/lib/validators"; import { ListTargetsResponse } from "@server/routers/target"; +import { ListRemoteExitNodesResponse } from "@server/routers/remoteExitNode/types"; import { ArrayElement } from "@server/types/ArrayElement"; import { useQuery } from "@tanstack/react-query"; import { @@ -81,6 +83,7 @@ import { CircleCheck, CircleX, Info, + InfoIcon, Plus, Settings, SquareArrowOutUpRight @@ -210,6 +213,13 @@ export default function Page() { orgQueries.sites({ orgId: orgId as string }) ); + const [remoteExitNodes, setRemoteExitNodes] = useState< + ListRemoteExitNodesResponse["remoteExitNodes"] + >([]); + const [loadingExitNodes, setLoadingExitNodes] = useState( + build === "saas" + ); + const [createLoading, setCreateLoading] = useState(false); const [showSnippets, setShowSnippets] = useState(false); const [niceId, setNiceId] = useState(""); @@ -224,6 +234,27 @@ export default function Page() { useState(null); const [healthCheckDialogOpen, setHealthCheckDialogOpen] = useState(false); + useEffect(() => { + if (build !== "saas") return; + + const fetchExitNodes = async () => { + try { + const res = await api.get< + AxiosResponse + >(`/org/${orgId}/remote-exit-nodes`); + if (res && res.status === 200) { + setRemoteExitNodes(res.data.data.remoteExitNodes); + } + } catch (e) { + console.error("Failed to fetch remote exit nodes:", e); + } finally { + setLoadingExitNodes(false); + } + }; + + fetchExitNodes(); + }, [orgId]); + const [isAdvancedMode, setIsAdvancedMode] = useState(() => { if (typeof window !== "undefined") { const saved = localStorage.getItem("create-advanced-mode"); @@ -289,15 +320,25 @@ export default function Page() { }, ...(!env.flags.allowRawResources ? [] - : [ - { - id: "raw" as ResourceType, - title: t("resourceRaw"), - description: build == "saas" ? t("resourceRawDescriptionCloud") : t("resourceRawDescription") - } - ]) + : build === "saas" && remoteExitNodes.length === 0 + ? [] + : [ + { + id: "raw" as ResourceType, + title: t("resourceRaw"), + description: + build == "saas" + ? t("resourceRawDescriptionCloud") + : t("resourceRawDescription") + } + ]) ]; + // In saas mode with no exit nodes, force HTTP + const showTypeSelector = + build !== "saas" || + (!loadingExitNodes && remoteExitNodes.length > 0); + const baseForm = useForm({ resolver: zodResolver(baseResourceFormSchema), defaultValues: { @@ -984,34 +1025,35 @@ export default function Page() { - {resourceTypes.length > 1 && ( - <> -
- - {t("type")} - -
+ {showTypeSelector && + resourceTypes.length > 1 && ( + <> +
+ + {t("type")} + +
- { - baseForm.setValue( - "http", - value === "http" - ); - // Update method default when switching resource type - addTargetForm.setValue( - "method", - value === "http" - ? "http" - : null - ); - }} - cols={2} - /> - - )} + { + baseForm.setValue( + "http", + value === "http" + ); + // Update method default when switching resource type + addTargetForm.setValue( + "method", + value === "http" + ? "http" + : null + ); + }} + cols={2} + /> + + )}
From f021b73458bea9c40d9fffc7cc3e6c009d585bc5 Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 11 Mar 2026 17:59:28 -0700 Subject: [PATCH 36/50] Add alert about domain error --- messages/en-US.json | 3 +- server/db/pg/schema/schema.ts | 3 +- server/db/sqlite/schema/schema.ts | 3 +- server/routers/domain/listDomains.ts | 3 +- .../settings/domains/[domainId]/page.tsx | 1 + src/components/DomainInfoCard.tsx | 20 ++++++++- src/components/DomainsTable.tsx | 41 ++++++++++++++++++- 7 files changed, 68 insertions(+), 6 deletions(-) diff --git a/messages/en-US.json b/messages/en-US.json index 6a35d79bb..3d5352293 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -2681,5 +2681,6 @@ "approvalsEmptyStateStep2Title": "Enable Device Approvals", "approvalsEmptyStateStep2Description": "Edit a role and enable the 'Require Device Approvals' option. Users with this role will need admin approval for new devices.", "approvalsEmptyStatePreviewDescription": "Preview: When enabled, pending device requests will appear here for review", - "approvalsEmptyStateButtonText": "Manage Roles" + "approvalsEmptyStateButtonText": "Manage Roles", + "domainErrorTitle": "We are having trouble verifying your domain" } diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index 504ea761f..b578b66e7 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -22,7 +22,8 @@ export const domains = pgTable("domains", { tries: integer("tries").notNull().default(0), certResolver: varchar("certResolver"), customCertResolver: varchar("customCertResolver"), - preferWildcardCert: boolean("preferWildcardCert") + preferWildcardCert: boolean("preferWildcardCert"), + errorMessage: text("errorMessage") }); export const dnsRecords = pgTable("dnsRecords", { diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index 2bd11ee0c..b02098896 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -13,7 +13,8 @@ export const domains = sqliteTable("domains", { failed: integer("failed", { mode: "boolean" }).notNull().default(false), tries: integer("tries").notNull().default(0), certResolver: text("certResolver"), - preferWildcardCert: integer("preferWildcardCert", { mode: "boolean" }) + preferWildcardCert: integer("preferWildcardCert", { mode: "boolean" }), + errorMessage: text("errorMessage") }); export const dnsRecords = sqliteTable("dnsRecords", { diff --git a/server/routers/domain/listDomains.ts b/server/routers/domain/listDomains.ts index 88cd5d7c7..085acf0c6 100644 --- a/server/routers/domain/listDomains.ts +++ b/server/routers/domain/listDomains.ts @@ -40,7 +40,8 @@ async function queryDomains(orgId: string, limit: number, offset: number) { tries: domains.tries, configManaged: domains.configManaged, certResolver: domains.certResolver, - preferWildcardCert: domains.preferWildcardCert + preferWildcardCert: domains.preferWildcardCert, + errorMessage: domains.errorMessage }) .from(orgDomains) .where(eq(orgDomains.orgId, orgId)) diff --git a/src/app/[orgId]/settings/domains/[domainId]/page.tsx b/src/app/[orgId]/settings/domains/[domainId]/page.tsx index 39ad02db2..cf23e81be 100644 --- a/src/app/[orgId]/settings/domains/[domainId]/page.tsx +++ b/src/app/[orgId]/settings/domains/[domainId]/page.tsx @@ -69,6 +69,7 @@ export default async function DomainSettingsPage({ failed={domain.failed} verified={domain.verified} type={domain.type} + errorMessage={domain.errorMessage} /> diff --git a/src/components/DomainInfoCard.tsx b/src/components/DomainInfoCard.tsx index e33998da2..7db17511b 100644 --- a/src/components/DomainInfoCard.tsx +++ b/src/components/DomainInfoCard.tsx @@ -10,17 +10,20 @@ import { import { useTranslations } from "next-intl"; import { Badge } from "./ui/badge"; import { useEnvContext } from "@app/hooks/useEnvContext"; +import { AlertTriangle } from "lucide-react"; type DomainInfoCardProps = { failed: boolean; verified: boolean; type: string | null; + errorMessage?: string | null; }; export default function DomainInfoCard({ failed, verified, - type + type, + errorMessage }: DomainInfoCardProps) { const t = useTranslations(); const env = useEnvContext(); @@ -39,6 +42,7 @@ export default function DomainInfoCard({ }; return ( +
@@ -79,5 +83,19 @@ export default function DomainInfoCard({ + {errorMessage && (failed || !verified) && ( + + + + {failed + ? t("domainErrorTitle", { fallback: "Domain Error" }) + : t("domainPendingErrorTitle", { fallback: "Verification Issue" })} + + + {errorMessage} + + + )} +
); } diff --git a/src/components/DomainsTable.tsx b/src/components/DomainsTable.tsx index ff23df67b..f5cb1ae74 100644 --- a/src/components/DomainsTable.tsx +++ b/src/components/DomainsTable.tsx @@ -27,6 +27,12 @@ import { DropdownMenuItem, DropdownMenuTrigger } from "./ui/dropdown-menu"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from "./ui/tooltip"; import Link from "next/link"; export type DomainRow = { @@ -39,6 +45,7 @@ export type DomainRow = { configManaged: boolean; certResolver: string; preferWildcardCert: boolean; + errorMessage?: string | null; }; type Props = { @@ -175,7 +182,7 @@ export default function DomainsTable({ domains, orgId }: Props) { ); }, cell: ({ row }) => { - const { verified, failed, type } = row.original; + const { verified, failed, type, errorMessage } = row.original; if (verified) { return type == "wildcard" ? ( {t("manual")} @@ -183,12 +190,44 @@ export default function DomainsTable({ domains, orgId }: Props) { {t("verified")} ); } else if (failed) { + if (errorMessage) { + return ( + + + + + {t("failed", { fallback: "Failed" })} + + + +

{errorMessage}

+
+
+
+ ); + } return ( {t("failed", { fallback: "Failed" })} ); } else { + if (errorMessage) { + return ( + + + + + {t("pending")} + + + +

{errorMessage}

+
+
+
+ ); + } return {t("pending")}; } } From 6c30f6db31443f91abfeeb1e1e68c51a486a60b9 Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 16:33:33 -0700 Subject: [PATCH 37/50] Dont send site if it missing public key --- server/routers/olm/buildConfiguration.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/routers/olm/buildConfiguration.ts b/server/routers/olm/buildConfiguration.ts index b506366bf..b6c64bd31 100644 --- a/server/routers/olm/buildConfiguration.ts +++ b/server/routers/olm/buildConfiguration.ts @@ -42,6 +42,13 @@ export async function buildSiteConfigurationForOlmClient( continue; } + if (!site.publicKey || site.publicKey == "") { // the site is not ready to accept new peers + logger.warn( + `Site ${site.siteId} has no public key, skipping` + ); + continue; + } + // if (site.lastHolePunch && now - site.lastHolePunch > 6 && relay) { // logger.warn( // `Site ${site.siteId} last hole punch is too old, skipping` From fde786ca8460c86013a96e06b1412af60ed88104 Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 17:10:46 -0700 Subject: [PATCH 38/50] Add todo --- server/lib/rebuildClientAssociations.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/lib/rebuildClientAssociations.ts b/server/lib/rebuildClientAssociations.ts index af43a6d00..46eb5c3ef 100644 --- a/server/lib/rebuildClientAssociations.ts +++ b/server/lib/rebuildClientAssociations.ts @@ -477,6 +477,7 @@ async function handleMessagesForSiteClients( } if (isAdd) { + // TODO: if we are in jit mode here should we really be sending this? await initPeerAddHandshake( // this will kick off the add peer process for the client client.clientId, @@ -1080,6 +1081,7 @@ async function handleMessagesForClientSites( continue; } + // TODO: if we are in jit mode here should we really be sending this? await initPeerAddHandshake( // this will kick off the add peer process for the client client.clientId, From beee1d692d254a7948740af33c929c31c643a646 Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 17:11:13 -0700 Subject: [PATCH 39/50] revert: telemetry comment --- server/lib/telemetry.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/lib/telemetry.ts b/server/lib/telemetry.ts index 4e957139f..fda59f394 100644 --- a/server/lib/telemetry.ts +++ b/server/lib/telemetry.ts @@ -21,13 +21,13 @@ class TelemetryClient { this.enabled = enabled; const dev = process.env.ENVIRONMENT !== "prod"; - // if (dev) { - // return; - // } + if (dev) { + return; + } - // if (build === "saas") { - // return; - // } + if (build === "saas") { + return; + } if (this.enabled) { this.client = new PostHog( From 63fd63c65ca96fbfd6d77137934172e2beda01ae Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 17:27:15 -0700 Subject: [PATCH 40/50] Send less data down --- server/routers/olm/buildConfiguration.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/server/routers/olm/buildConfiguration.ts b/server/routers/olm/buildConfiguration.ts index 6bef8d56f..bc2611b1c 100644 --- a/server/routers/olm/buildConfiguration.ts +++ b/server/routers/olm/buildConfiguration.ts @@ -25,12 +25,12 @@ export async function buildSiteConfigurationForOlmClient( ) { const siteConfigurations: { siteId: number; - name: string | null; - endpoint: string | null; - publicKey: string | null; - serverIP: string | null; - serverPort: number | null; - remoteSubnets: string[]; + name?: string + endpoint?: string + publicKey?: string + serverIP?: string | null + serverPort?: number | null + remoteSubnets?: string[]; aliases: Alias[]; }[] = []; @@ -73,15 +73,9 @@ export async function buildSiteConfigurationForOlmClient( // Add site configuration to the array siteConfigurations.push({ siteId: site.siteId, - name: null, // this is just to sync the aliases - endpoint: null, - publicKey: null, - serverIP: null, - serverPort: null, // remoteSubnets: generateRemoteSubnets( // allSiteResources.map(({ siteResources }) => siteResources) // ), - remoteSubnets: [], aliases: generateAliasConfig( allSiteResources.map(({ siteResources }) => siteResources) ) From cccf236042d677cc9a2e5bd9449e842eec94f1ac Mon Sep 17 00:00:00 2001 From: Owen Date: Thu, 12 Mar 2026 17:49:21 -0700 Subject: [PATCH 41/50] Add optional compression --- server/private/routers/ws/ws.ts | 57 +++++++++---- server/routers/client/targets.ts | 132 ++++++++++++++----------------- server/routers/ws/types.ts | 3 +- server/routers/ws/ws.ts | 48 ++++++++--- 4 files changed, 139 insertions(+), 101 deletions(-) diff --git a/server/private/routers/ws/ws.ts b/server/private/routers/ws/ws.ts index 7d1769bca..467cedc5f 100644 --- a/server/private/routers/ws/ws.ts +++ b/server/private/routers/ws/ws.ts @@ -12,6 +12,7 @@ */ import { Router, Request, Response } from "express"; +import zlib from "zlib"; import { Server as HttpServer } from "http"; import { WebSocket, WebSocketServer } from "ws"; import { Socket } from "net"; @@ -57,11 +58,13 @@ const MAX_PENDING_MESSAGES = 50; // Maximum messages to queue during connection const processMessage = async ( ws: AuthenticatedWebSocket, data: Buffer, + isBinary: boolean, clientId: string, clientType: ClientType ): Promise => { try { - const message: WSMessage = JSON.parse(data.toString()); + const messageBuffer = isBinary ? zlib.gunzipSync(data) : data; + const message: WSMessage = JSON.parse(messageBuffer.toString()); // logger.debug( // `Processing message from ${clientType.toUpperCase()} ID: ${clientId}, type: ${message.type}` @@ -163,8 +166,10 @@ const processPendingMessages = async ( ); const jobs = []; - for (const messageData of ws.pendingMessages) { - jobs.push(processMessage(ws, messageData, clientId, clientType)); + for (const pending of ws.pendingMessages) { + jobs.push( + processMessage(ws, pending.data, pending.isBinary, clientId, clientType) + ); } await Promise.all(jobs); @@ -502,11 +507,20 @@ const sendToClientLocal = async ( }; const messageString = JSON.stringify(messageWithVersion); - clients.forEach((client) => { - if (client.readyState === WebSocket.OPEN) { - client.send(messageString); - } - }); + if (options.compress) { + const compressed = zlib.gzipSync(Buffer.from(messageString, "utf8")); + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(compressed); + } + }); + } else { + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(messageString); + } + }); + } return true; }; @@ -532,11 +546,22 @@ const broadcastToAllExceptLocal = async ( configVersion }; - clients.forEach((client) => { - if (client.readyState === WebSocket.OPEN) { - client.send(JSON.stringify(messageWithVersion)); - } - }); + if (options.compress) { + const compressed = zlib.gzipSync( + Buffer.from(JSON.stringify(messageWithVersion), "utf8") + ); + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(compressed); + } + }); + } else { + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(messageWithVersion)); + } + }); + } } } }; @@ -762,7 +787,7 @@ const setupConnection = async ( } // Set up message handler FIRST to prevent race condition - ws.on("message", async (data) => { + ws.on("message", async (data, isBinary) => { if (!ws.isFullyConnected) { // Queue message for later processing with limits ws.pendingMessages = ws.pendingMessages || []; @@ -777,11 +802,11 @@ const setupConnection = async ( logger.debug( `Queueing message from ${clientType.toUpperCase()} ID: ${clientId} (connection not fully established)` ); - ws.pendingMessages.push(data as Buffer); + ws.pendingMessages.push({ data: data as Buffer, isBinary }); return; } - await processMessage(ws, data as Buffer, clientId, clientType); + await processMessage(ws, data as Buffer, isBinary, clientId, clientType); }); // Set up other event handlers before async operations diff --git a/server/routers/client/targets.ts b/server/routers/client/targets.ts index bf612d352..8cac9e05d 100644 --- a/server/routers/client/targets.ts +++ b/server/routers/client/targets.ts @@ -4,48 +4,29 @@ import { Alias, SubnetProxyTarget } from "@server/lib/ip"; import logger from "@server/logger"; import { eq } from "drizzle-orm"; -const BATCH_SIZE = 50; -const BATCH_DELAY_MS = 50; - -function sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -function chunkArray(array: T[], size: number): T[][] { - const chunks: T[][] = []; - for (let i = 0; i < array.length; i += size) { - chunks.push(array.slice(i, i + size)); - } - return chunks; -} - export async function addTargets(newtId: string, targets: SubnetProxyTarget[]) { - const batches = chunkArray(targets, BATCH_SIZE); - for (let i = 0; i < batches.length; i++) { - if (i > 0) { - await sleep(BATCH_DELAY_MS); - } - await sendToClient(newtId, { + await sendToClient( + newtId, + { type: `newt/wg/targets/add`, - data: batches[i] - }, { incrementConfigVersion: true }); - } + data: targets + }, + { incrementConfigVersion: true } + ); } export async function removeTargets( newtId: string, targets: SubnetProxyTarget[] ) { - const batches = chunkArray(targets, BATCH_SIZE); - for (let i = 0; i < batches.length; i++) { - if (i > 0) { - await sleep(BATCH_DELAY_MS); - } - await sendToClient(newtId, { + await sendToClient( + newtId, + { type: `newt/wg/targets/remove`, - data: batches[i] - },{ incrementConfigVersion: true }); - } + data: targets + }, + { incrementConfigVersion: true } + ); } export async function updateTargets( @@ -55,24 +36,19 @@ export async function updateTargets( newTargets: SubnetProxyTarget[]; } ) { - const oldBatches = chunkArray(targets.oldTargets, BATCH_SIZE); - const newBatches = chunkArray(targets.newTargets, BATCH_SIZE); - const maxBatches = Math.max(oldBatches.length, newBatches.length); - - for (let i = 0; i < maxBatches; i++) { - if (i > 0) { - await sleep(BATCH_DELAY_MS); - } - await sendToClient(newtId, { + await sendToClient( + newtId, + { type: `newt/wg/targets/update`, data: { - oldTargets: oldBatches[i] || [], - newTargets: newBatches[i] || [] + oldTargets: targets.oldTargets, + newTargets: targets.newTargets } - }, { incrementConfigVersion: true }).catch((error) => { - logger.warn(`Error sending message:`, error); - }); - } + }, + { incrementConfigVersion: true } + ).catch((error) => { + logger.warn(`Error sending message:`, error); + }); } export async function addPeerData( @@ -94,14 +70,18 @@ export async function addPeerData( olmId = olm.olmId; } - await sendToClient(olmId, { - type: `olm/wg/peer/data/add`, - data: { - siteId: siteId, - remoteSubnets: remoteSubnets, - aliases: aliases - } - }, { incrementConfigVersion: true }).catch((error) => { + await sendToClient( + olmId, + { + type: `olm/wg/peer/data/add`, + data: { + siteId: siteId, + remoteSubnets: remoteSubnets, + aliases: aliases + } + }, + { incrementConfigVersion: true } + ).catch((error) => { logger.warn(`Error sending message:`, error); }); } @@ -125,14 +105,18 @@ export async function removePeerData( olmId = olm.olmId; } - await sendToClient(olmId, { - type: `olm/wg/peer/data/remove`, - data: { - siteId: siteId, - remoteSubnets: remoteSubnets, - aliases: aliases - } - }, { incrementConfigVersion: true }).catch((error) => { + await sendToClient( + olmId, + { + type: `olm/wg/peer/data/remove`, + data: { + siteId: siteId, + remoteSubnets: remoteSubnets, + aliases: aliases + } + }, + { incrementConfigVersion: true } + ).catch((error) => { logger.warn(`Error sending message:`, error); }); } @@ -166,14 +150,18 @@ export async function updatePeerData( olmId = olm.olmId; } - await sendToClient(olmId, { - type: `olm/wg/peer/data/update`, - data: { - siteId: siteId, - ...remoteSubnets, - ...aliases - } - }, { incrementConfigVersion: true }).catch((error) => { + await sendToClient( + olmId, + { + type: `olm/wg/peer/data/update`, + data: { + siteId: siteId, + ...remoteSubnets, + ...aliases + } + }, + { incrementConfigVersion: true } + ).catch((error) => { logger.warn(`Error sending message:`, error); }); } diff --git a/server/routers/ws/types.ts b/server/routers/ws/types.ts index 4be68883e..e539954ce 100644 --- a/server/routers/ws/types.ts +++ b/server/routers/ws/types.ts @@ -24,7 +24,7 @@ export interface AuthenticatedWebSocket extends WebSocket { clientType?: ClientType; connectionId?: string; isFullyConnected?: boolean; - pendingMessages?: Buffer[]; + pendingMessages?: { data: Buffer; isBinary: boolean }[]; configVersion?: number; } @@ -73,6 +73,7 @@ export type MessageHandler = ( // Options for sending messages with config version tracking export interface SendMessageOptions { incrementConfigVersion?: boolean; + compress?: boolean; } // Redis message type for cross-node communication diff --git a/server/routers/ws/ws.ts b/server/routers/ws/ws.ts index 32432d997..c7085fba9 100644 --- a/server/routers/ws/ws.ts +++ b/server/routers/ws/ws.ts @@ -1,4 +1,5 @@ import { Router, Request, Response } from "express"; +import zlib from "zlib"; import { Server as HttpServer } from "http"; import { WebSocket, WebSocketServer } from "ws"; import { Socket } from "net"; @@ -116,11 +117,20 @@ const sendToClientLocal = async ( }; const messageString = JSON.stringify(messageWithVersion); - clients.forEach((client) => { - if (client.readyState === WebSocket.OPEN) { - client.send(messageString); - } - }); + if (options.compress) { + const compressed = zlib.gzipSync(Buffer.from(messageString, "utf8")); + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(compressed); + } + }); + } else { + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(messageString); + } + }); + } return true; }; @@ -147,11 +157,22 @@ const broadcastToAllExceptLocal = async ( ...message, configVersion }; - clients.forEach((client) => { - if (client.readyState === WebSocket.OPEN) { - client.send(JSON.stringify(messageWithVersion)); - } - }); + if (options.compress) { + const compressed = zlib.gzipSync( + Buffer.from(JSON.stringify(messageWithVersion), "utf8") + ); + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(compressed); + } + }); + } else { + clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(messageWithVersion)); + } + }); + } } }); }; @@ -286,9 +307,12 @@ const setupConnection = async ( clientType === "newt" ? (client as Newt).newtId : (client as Olm).olmId; await addClient(clientType, clientId, ws); - ws.on("message", async (data) => { + ws.on("message", async (data, isBinary) => { try { - const message: WSMessage = JSON.parse(data.toString()); + const messageBuffer = isBinary + ? zlib.gunzipSync(data as Buffer) + : (data as Buffer); + const message: WSMessage = JSON.parse(messageBuffer.toString()); if (!message.type || typeof message.type !== "string") { throw new Error( From dc4e0253de3ee61a98a365a67521f4404a82ddab Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 13 Mar 2026 11:46:03 -0700 Subject: [PATCH 42/50] Add message compression for large messages --- server/lib/blueprints/applyBlueprint.ts | 2 +- server/lib/clientVersionChecks.ts | 20 ++++++++++ server/lib/rebuildClientAssociations.ts | 30 ++++++++++++--- server/private/routers/ws/ws.ts | 35 +++++++++++++++--- server/routers/client/targets.ts | 37 +++++++++++++------ server/routers/newt/buildConfiguration.ts | 6 +-- server/routers/newt/handleGetConfigMessage.ts | 4 ++ .../routers/newt/handleNewtRegisterMessage.ts | 8 ++-- server/routers/newt/sync.ts | 29 +++++++++------ server/routers/newt/targets.ts | 11 +++--- .../routers/olm/handleOlmRegisterMessage.ts | 4 ++ server/routers/olm/peers.ts | 19 +++++++--- server/routers/olm/sync.ts | 34 +++++++++++------ .../siteResource/updateSiteResource.ts | 2 +- server/routers/target/createTarget.ts | 2 +- server/routers/target/updateTarget.ts | 2 +- 16 files changed, 179 insertions(+), 66 deletions(-) create mode 100644 server/lib/clientVersionChecks.ts diff --git a/server/lib/blueprints/applyBlueprint.ts b/server/lib/blueprints/applyBlueprint.ts index ac2f9508e..a304bb392 100644 --- a/server/lib/blueprints/applyBlueprint.ts +++ b/server/lib/blueprints/applyBlueprint.ts @@ -107,7 +107,7 @@ export async function applyBlueprint({ [target], matchingHealthcheck ? [matchingHealthcheck] : [], result.proxyResource.protocol, - result.proxyResource.proxyPort + site.newt.version ); } } diff --git a/server/lib/clientVersionChecks.ts b/server/lib/clientVersionChecks.ts new file mode 100644 index 000000000..330959e7c --- /dev/null +++ b/server/lib/clientVersionChecks.ts @@ -0,0 +1,20 @@ +import semver from "semver"; + +export function canCompress( + clientVersion: string | null | undefined, + type: "newt" | "olm" +): boolean { + try { + if (!clientVersion) return false; + // check if it is a valid semver + if (!semver.valid(clientVersion)) return false; + if (type === "newt") { + return semver.gte(clientVersion, "1.10.3"); + } else if (type === "olm") { + return semver.gte(clientVersion, "1.4.3"); + } + return false; + } catch { + return false; + } +} diff --git a/server/lib/rebuildClientAssociations.ts b/server/lib/rebuildClientAssociations.ts index 46eb5c3ef..121e2c7f0 100644 --- a/server/lib/rebuildClientAssociations.ts +++ b/server/lib/rebuildClientAssociations.ts @@ -670,7 +670,11 @@ async function handleSubnetProxyTargetUpdates( `Adding ${targetsToAdd.length} subnet proxy targets for siteResource ${siteResource.siteResourceId}` ); proxyJobs.push( - addSubnetProxyTargets(newt.newtId, targetsToAdd) + addSubnetProxyTargets( + newt.newtId, + targetsToAdd, + newt.version + ) ); } @@ -706,7 +710,11 @@ async function handleSubnetProxyTargetUpdates( `Removing ${targetsToRemove.length} subnet proxy targets for siteResource ${siteResource.siteResourceId}` ); proxyJobs.push( - removeSubnetProxyTargets(newt.newtId, targetsToRemove) + removeSubnetProxyTargets( + newt.newtId, + targetsToRemove, + newt.version + ) ); } @@ -1148,7 +1156,7 @@ async function handleMessagesForClientResources( // Add subnet proxy targets for each site for (const [siteId, resources] of addedBySite.entries()) { const [newt] = await trx - .select({ newtId: newts.newtId }) + .select({ newtId: newts.newtId, version: newts.version }) .from(newts) .where(eq(newts.siteId, siteId)) .limit(1); @@ -1170,7 +1178,13 @@ async function handleMessagesForClientResources( ]); if (targets.length > 0) { - proxyJobs.push(addSubnetProxyTargets(newt.newtId, targets)); + proxyJobs.push( + addSubnetProxyTargets( + newt.newtId, + targets, + newt.version + ) + ); } try { @@ -1219,7 +1233,7 @@ async function handleMessagesForClientResources( // Remove subnet proxy targets for each site for (const [siteId, resources] of removedBySite.entries()) { const [newt] = await trx - .select({ newtId: newts.newtId }) + .select({ newtId: newts.newtId, version: newts.version }) .from(newts) .where(eq(newts.siteId, siteId)) .limit(1); @@ -1242,7 +1256,11 @@ async function handleMessagesForClientResources( if (targets.length > 0) { proxyJobs.push( - removeSubnetProxyTargets(newt.newtId, targets) + removeSubnetProxyTargets( + newt.newtId, + targets, + newt.version + ) ); } diff --git a/server/private/routers/ws/ws.ts b/server/private/routers/ws/ws.ts index 467cedc5f..f10df2863 100644 --- a/server/private/routers/ws/ws.ts +++ b/server/private/routers/ws/ws.ts @@ -168,7 +168,13 @@ const processPendingMessages = async ( const jobs = []; for (const pending of ws.pendingMessages) { jobs.push( - processMessage(ws, pending.data, pending.isBinary, clientId, clientType) + processMessage( + ws, + pending.data, + pending.isBinary, + clientId, + clientType + ) ); } @@ -330,7 +336,9 @@ const addClient = async ( // Check Redis first if enabled if (redisManager.isRedisEnabled()) { try { - const redisVersion = await redisManager.get(getConfigVersionKey(clientId)); + const redisVersion = await redisManager.get( + getConfigVersionKey(clientId) + ); if (redisVersion !== null) { configVersion = parseInt(redisVersion, 10); // Sync to local cache @@ -342,7 +350,10 @@ const addClient = async ( } else { // Use local cache version and sync to Redis configVersion = clientConfigVersions.get(clientId) || 0; - await redisManager.set(getConfigVersionKey(clientId), configVersion.toString()); + await redisManager.set( + getConfigVersionKey(clientId), + configVersion.toString() + ); } } catch (error) { logger.error("Failed to get/set config version in Redis:", error); @@ -437,7 +448,9 @@ const removeClient = async ( }; // Helper to get the current config version for a client -const getClientConfigVersion = async (clientId: string): Promise => { +const getClientConfigVersion = async ( + clientId: string +): Promise => { // Try Redis first if available if (redisManager.isRedisEnabled()) { try { @@ -508,7 +521,13 @@ const sendToClientLocal = async ( const messageString = JSON.stringify(messageWithVersion); if (options.compress) { + logger.debug( + `Message size before compression: ${messageString.length} bytes` + ); const compressed = zlib.gzipSync(Buffer.from(messageString, "utf8")); + logger.debug( + `Message size after compression: ${compressed.length} bytes` + ); clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send(compressed); @@ -806,7 +825,13 @@ const setupConnection = async ( return; } - await processMessage(ws, data as Buffer, isBinary, clientId, clientType); + await processMessage( + ws, + data as Buffer, + isBinary, + clientId, + clientType + ); }); // Set up other event handlers before async operations diff --git a/server/routers/client/targets.ts b/server/routers/client/targets.ts index 8cac9e05d..94d41a4d1 100644 --- a/server/routers/client/targets.ts +++ b/server/routers/client/targets.ts @@ -1,23 +1,29 @@ import { sendToClient } from "#dynamic/routers/ws"; import { db, olms, Transaction } from "@server/db"; +import { canCompress } from "@server/lib/clientVersionChecks"; import { Alias, SubnetProxyTarget } from "@server/lib/ip"; import logger from "@server/logger"; import { eq } from "drizzle-orm"; -export async function addTargets(newtId: string, targets: SubnetProxyTarget[]) { +export async function addTargets( + newtId: string, + targets: SubnetProxyTarget[], + version?: string | null +) { await sendToClient( newtId, { type: `newt/wg/targets/add`, data: targets }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "newt") } ); } export async function removeTargets( newtId: string, - targets: SubnetProxyTarget[] + targets: SubnetProxyTarget[], + version?: string | null ) { await sendToClient( newtId, @@ -25,7 +31,7 @@ export async function removeTargets( type: `newt/wg/targets/remove`, data: targets }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "newt") } ); } @@ -34,7 +40,8 @@ export async function updateTargets( targets: { oldTargets: SubnetProxyTarget[]; newTargets: SubnetProxyTarget[]; - } + }, + version?: string | null ) { await sendToClient( newtId, @@ -45,7 +52,7 @@ export async function updateTargets( newTargets: targets.newTargets } }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "newt") } ).catch((error) => { logger.warn(`Error sending message:`, error); }); @@ -56,7 +63,8 @@ export async function addPeerData( siteId: number, remoteSubnets: string[], aliases: Alias[], - olmId?: string + olmId?: string, + version?: string | null ) { if (!olmId) { const [olm] = await db @@ -68,6 +76,7 @@ export async function addPeerData( return; // ignore this because an olm might not be associated with the client anymore } olmId = olm.olmId; + version = olm.version; } await sendToClient( @@ -80,7 +89,7 @@ export async function addPeerData( aliases: aliases } }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "olm") } ).catch((error) => { logger.warn(`Error sending message:`, error); }); @@ -91,7 +100,8 @@ export async function removePeerData( siteId: number, remoteSubnets: string[], aliases: Alias[], - olmId?: string + olmId?: string, + version?: string | null ) { if (!olmId) { const [olm] = await db @@ -103,6 +113,7 @@ export async function removePeerData( return; } olmId = olm.olmId; + version = olm.version; } await sendToClient( @@ -115,7 +126,7 @@ export async function removePeerData( aliases: aliases } }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "olm") } ).catch((error) => { logger.warn(`Error sending message:`, error); }); @@ -136,7 +147,8 @@ export async function updatePeerData( newAliases: Alias[]; } | undefined, - olmId?: string + olmId?: string, + version?: string | null ) { if (!olmId) { const [olm] = await db @@ -148,6 +160,7 @@ export async function updatePeerData( return; } olmId = olm.olmId; + version = olm.version; } await sendToClient( @@ -160,7 +173,7 @@ export async function updatePeerData( ...aliases } }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "olm") } ).catch((error) => { logger.warn(`Error sending message:`, error); }); diff --git a/server/routers/newt/buildConfiguration.ts b/server/routers/newt/buildConfiguration.ts index 522b3b8dc..579316336 100644 --- a/server/routers/newt/buildConfiguration.ts +++ b/server/routers/newt/buildConfiguration.ts @@ -243,9 +243,9 @@ export async function buildTargetConfigurationForNewtClient(siteId: number) { !target.hcInterval || !target.hcMethod ) { - logger.debug( - `Skipping adding target health check ${target.targetId} due to missing health check fields` - ); + // logger.debug( + // `Skipping adding target health check ${target.targetId} due to missing health check fields` + // ); return null; // Skip targets with missing health check fields } diff --git a/server/routers/newt/handleGetConfigMessage.ts b/server/routers/newt/handleGetConfigMessage.ts index 24cca17a2..d536e9828 100644 --- a/server/routers/newt/handleGetConfigMessage.ts +++ b/server/routers/newt/handleGetConfigMessage.ts @@ -6,6 +6,7 @@ import { db, ExitNode, exitNodes, Newt, sites } from "@server/db"; import { eq } from "drizzle-orm"; import { sendToExitNode } from "#dynamic/lib/exitNodes"; import { buildClientConfigurationForNewtClient } from "./buildConfiguration"; +import { canCompress } from "@server/lib/clientVersionChecks"; const inputSchema = z.object({ publicKey: z.string(), @@ -135,6 +136,9 @@ export const handleGetConfigMessage: MessageHandler = async (context) => { targets } }, + options: { + compress: canCompress(newt.version, "newt") + }, broadcast: false, excludeSender: false }; diff --git a/server/routers/newt/handleNewtRegisterMessage.ts b/server/routers/newt/handleNewtRegisterMessage.ts index 595430df5..90034cfbf 100644 --- a/server/routers/newt/handleNewtRegisterMessage.ts +++ b/server/routers/newt/handleNewtRegisterMessage.ts @@ -5,9 +5,7 @@ import { eq } from "drizzle-orm"; import { addPeer, deletePeer } from "../gerbil/peers"; import logger from "@server/logger"; import config from "@server/lib/config"; -import { - findNextAvailableCidr, -} from "@server/lib/ip"; +import { findNextAvailableCidr } from "@server/lib/ip"; import { selectBestExitNode, verifyExitNodeOrgAccess @@ -15,6 +13,7 @@ import { import { fetchContainers } from "./dockerSocket"; import { lockManager } from "#dynamic/lib/lock"; import { buildTargetConfigurationForNewtClient } from "./buildConfiguration"; +import { canCompress } from "@server/lib/clientVersionChecks"; export type ExitNodePingResult = { exitNodeId: number; @@ -215,6 +214,9 @@ export const handleNewtRegisterMessage: MessageHandler = async (context) => { healthCheckTargets: validHealthCheckTargets } }, + options: { + compress: canCompress(newt.version, "newt") + }, broadcast: false, // Send to all clients excludeSender: false // Include sender in broadcast }; diff --git a/server/routers/newt/sync.ts b/server/routers/newt/sync.ts index e6f465e55..6fce13ff3 100644 --- a/server/routers/newt/sync.ts +++ b/server/routers/newt/sync.ts @@ -6,6 +6,7 @@ import { buildClientConfigurationForNewtClient, buildTargetConfigurationForNewtClient } from "./buildConfiguration"; +import { canCompress } from "@server/lib/clientVersionChecks"; export async function sendNewtSyncMessage(newt: Newt, site: Site) { const { tcpTargets, udpTargets, validHealthCheckTargets } = @@ -24,18 +25,24 @@ export async function sendNewtSyncMessage(newt: Newt, site: Site) { exitNode ); - await sendToClient(newt.newtId, { - type: "newt/sync", - data: { - proxyTargets: { - udp: udpTargets, - tcp: tcpTargets - }, - healthCheckTargets: validHealthCheckTargets, - peers: peers, - clientTargets: targets + await sendToClient( + newt.newtId, + { + type: "newt/sync", + data: { + proxyTargets: { + udp: udpTargets, + tcp: tcpTargets + }, + healthCheckTargets: validHealthCheckTargets, + peers: peers, + clientTargets: targets + } + }, + { + compress: canCompress(newt.version, "newt") } - }).catch((error) => { + ).catch((error) => { logger.warn(`Error sending newt sync message:`, error); }); } diff --git a/server/routers/newt/targets.ts b/server/routers/newt/targets.ts index 6318861e4..6a523ebe9 100644 --- a/server/routers/newt/targets.ts +++ b/server/routers/newt/targets.ts @@ -2,13 +2,14 @@ import { Target, TargetHealthCheck, db, targetHealthCheck } from "@server/db"; import { sendToClient } from "#dynamic/routers/ws"; import logger from "@server/logger"; import { eq, inArray } from "drizzle-orm"; +import { canCompress } from "@server/lib/clientVersionChecks"; export async function addTargets( newtId: string, targets: Target[], healthCheckData: TargetHealthCheck[], protocol: string, - port: number | null = null + version?: string | null ) { //create a list of udp and tcp targets const payloadTargets = targets.map((target) => { @@ -22,7 +23,7 @@ export async function addTargets( data: { targets: payloadTargets } - }, { incrementConfigVersion: true }); + }, { incrementConfigVersion: true, compress: canCompress(version, "newt") }); // Create a map for quick lookup const healthCheckMap = new Map(); @@ -103,14 +104,14 @@ export async function addTargets( data: { targets: validHealthCheckTargets } - }, { incrementConfigVersion: true }); + }, { incrementConfigVersion: true, compress: canCompress(version, "newt") }); } export async function removeTargets( newtId: string, targets: Target[], protocol: string, - port: number | null = null + version?: string | null ) { //create a list of udp and tcp targets const payloadTargets = targets.map((target) => { @@ -135,5 +136,5 @@ export async function removeTargets( data: { ids: healthCheckTargets } - }, { incrementConfigVersion: true }); + }, { incrementConfigVersion: true, compress: canCompress(version, "newt") }); } diff --git a/server/routers/olm/handleOlmRegisterMessage.ts b/server/routers/olm/handleOlmRegisterMessage.ts index 68aa1b624..065aeeaa6 100644 --- a/server/routers/olm/handleOlmRegisterMessage.ts +++ b/server/routers/olm/handleOlmRegisterMessage.ts @@ -19,6 +19,7 @@ import { OlmErrorCodes, sendOlmError } from "./error"; import { handleFingerprintInsertion } from "./fingerprintingUtils"; import { Alias } from "@server/lib/ip"; import { build } from "@server/build"; +import { canCompress } from "@server/lib/clientVersionChecks"; export const handleOlmRegisterMessage: MessageHandler = async (context) => { logger.info("Handling register olm message!"); @@ -295,6 +296,9 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { utilitySubnet: org.utilitySubnet } }, + options: { + compress: canCompress(olm.version, "olm") + }, broadcast: false, excludeSender: false }; diff --git a/server/routers/olm/peers.ts b/server/routers/olm/peers.ts index 06621cac9..05e153fea 100644 --- a/server/routers/olm/peers.ts +++ b/server/routers/olm/peers.ts @@ -1,5 +1,6 @@ import { sendToClient } from "#dynamic/routers/ws"; import { clientSitesAssociationsCache, db, olms } from "@server/db"; +import { canCompress } from "@server/lib/clientVersionChecks"; import config from "@server/lib/config"; import logger from "@server/logger"; import { and, eq } from "drizzle-orm"; @@ -18,7 +19,8 @@ export async function addPeer( remoteSubnets: string[] | null; // optional, comma-separated list of subnets that this site can access aliases: Alias[]; }, - olmId?: string + olmId?: string, + version?: string | null ) { if (!olmId) { const [olm] = await db @@ -30,6 +32,7 @@ export async function addPeer( return; // ignore this because an olm might not be associated with the client anymore } olmId = olm.olmId; + version = olm.version; } await sendToClient( @@ -48,7 +51,7 @@ export async function addPeer( aliases: peer.aliases } }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "olm") } ).catch((error) => { logger.warn(`Error sending message:`, error); }); @@ -60,7 +63,8 @@ export async function deletePeer( clientId: number, siteId: number, publicKey: string, - olmId?: string + olmId?: string, + version?: string | null ) { if (!olmId) { const [olm] = await db @@ -72,6 +76,7 @@ export async function deletePeer( return; } olmId = olm.olmId; + version = olm.version; } await sendToClient( @@ -83,7 +88,7 @@ export async function deletePeer( siteId: siteId } }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "olm") } ).catch((error) => { logger.warn(`Error sending message:`, error); }); @@ -103,7 +108,8 @@ export async function updatePeer( remoteSubnets?: string[] | null; // optional, comma-separated list of subnets that aliases?: Alias[] | null; }, - olmId?: string + olmId?: string, + version?: string | null ) { if (!olmId) { const [olm] = await db @@ -115,6 +121,7 @@ export async function updatePeer( return; } olmId = olm.olmId; + version = olm.version; } await sendToClient( @@ -132,7 +139,7 @@ export async function updatePeer( aliases: peer.aliases } }, - { incrementConfigVersion: true } + { incrementConfigVersion: true, compress: canCompress(version, "olm") } ).catch((error) => { logger.warn(`Error sending message:`, error); }); diff --git a/server/routers/olm/sync.ts b/server/routers/olm/sync.ts index d4ecd22c1..c994b2c73 100644 --- a/server/routers/olm/sync.ts +++ b/server/routers/olm/sync.ts @@ -1,9 +1,17 @@ -import { Client, db, exitNodes, Olm, sites, clientSitesAssociationsCache } from "@server/db"; +import { + Client, + db, + exitNodes, + Olm, + sites, + clientSitesAssociationsCache +} from "@server/db"; import { buildSiteConfigurationForOlmClient } from "./buildConfiguration"; import { sendToClient } from "#dynamic/routers/ws"; import logger from "@server/logger"; import { eq, inArray } from "drizzle-orm"; import config from "@server/lib/config"; +import { canCompress } from "@server/lib/clientVersionChecks"; export async function sendOlmSyncMessage(olm: Olm, client: Client) { // NOTE: WE ARE HARDCODING THE RELAY PARAMETER TO FALSE HERE BUT IN THE REGISTER MESSAGE ITS DEFINED BY THE CLIENT @@ -17,10 +25,7 @@ export async function sendOlmSyncMessage(olm: Olm, client: Client) { const clientSites = await db .select() .from(clientSitesAssociationsCache) - .innerJoin( - sites, - eq(sites.siteId, clientSitesAssociationsCache.siteId) - ) + .innerJoin(sites, eq(sites.siteId, clientSitesAssociationsCache.siteId)) .where(eq(clientSitesAssociationsCache.clientId, client.clientId)); // Extract unique exit node IDs @@ -68,13 +73,20 @@ export async function sendOlmSyncMessage(olm: Olm, client: Client) { logger.debug("sendOlmSyncMessage: sending sync message"); - await sendToClient(olm.olmId, { - type: "olm/sync", - data: { - sites: siteConfigurations, - exitNodes: exitNodesData + await sendToClient( + olm.olmId, + { + type: "olm/sync", + data: { + sites: siteConfigurations, + exitNodes: exitNodesData + } + }, + + { + compress: canCompress(olm.version, "olm") } - }).catch((error) => { + ).catch((error) => { logger.warn(`Error sending olm sync message:`, error); }); } diff --git a/server/routers/siteResource/updateSiteResource.ts b/server/routers/siteResource/updateSiteResource.ts index b748e26d3..596ed9a3f 100644 --- a/server/routers/siteResource/updateSiteResource.ts +++ b/server/routers/siteResource/updateSiteResource.ts @@ -620,7 +620,7 @@ export async function handleMessagingForUpdatedSiteResource( await updateTargets(newt.newtId, { oldTargets: oldTargets, newTargets: newTargets - }); + }, newt.version); } const olmJobs: Promise[] = []; diff --git a/server/routers/target/createTarget.ts b/server/routers/target/createTarget.ts index 47495cbbc..ba52d85a1 100644 --- a/server/routers/target/createTarget.ts +++ b/server/routers/target/createTarget.ts @@ -264,7 +264,7 @@ export async function createTarget( newTarget, healthCheck, resource.protocol, - resource.proxyPort + newt.version ); } } diff --git a/server/routers/target/updateTarget.ts b/server/routers/target/updateTarget.ts index c5321e986..dd31f5f1b 100644 --- a/server/routers/target/updateTarget.ts +++ b/server/routers/target/updateTarget.ts @@ -262,7 +262,7 @@ export async function updateTarget( [updatedTarget], [updatedHc], resource.protocol, - resource.proxyPort + newt.version ); } } From 75ab0748056caad39554c5f38ddef32aeede57ed Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 13 Mar 2026 12:06:01 -0700 Subject: [PATCH 43/50] Attempt to improve handling bandwidth tracking --- server/cleanup.ts | 6 +- server/private/cleanup.ts | 6 +- server/routers/gerbil/receiveBandwidth.ts | 446 ++++++++++-------- .../newt/handleReceiveBandwidthMessage.ts | 142 ++++-- 4 files changed, 357 insertions(+), 243 deletions(-) diff --git a/server/cleanup.ts b/server/cleanup.ts index e494fcdc9..137654827 100644 --- a/server/cleanup.ts +++ b/server/cleanup.ts @@ -1,6 +1,10 @@ +import { flushBandwidthToDb } from "@server/routers/newt/handleReceiveBandwidthMessage"; +import { flushSiteBandwidthToDb } from "@server/routers/gerbil/receiveBandwidth"; import { cleanup as wsCleanup } from "#dynamic/routers/ws"; async function cleanup() { + await flushBandwidthToDb(); + await flushSiteBandwidthToDb(); await wsCleanup(); process.exit(0); @@ -10,4 +14,4 @@ export async function initCleanup() { // Handle process termination process.on("SIGTERM", () => cleanup()); process.on("SIGINT", () => cleanup()); -} +} \ No newline at end of file diff --git a/server/private/cleanup.ts b/server/private/cleanup.ts index e9b305270..0bd9822dd 100644 --- a/server/private/cleanup.ts +++ b/server/private/cleanup.ts @@ -13,8 +13,12 @@ import { rateLimitService } from "#private/lib/rateLimit"; import { cleanup as wsCleanup } from "#private/routers/ws"; +import { flushBandwidthToDb } from "@server/routers/newt/handleReceiveBandwidthMessage"; +import { flushSiteBandwidthToDb } from "@server/routers/gerbil/receiveBandwidth"; async function cleanup() { + await flushBandwidthToDb(); + await flushSiteBandwidthToDb(); await rateLimitService.cleanup(); await wsCleanup(); @@ -25,4 +29,4 @@ export async function initCleanup() { // Handle process termination process.on("SIGTERM", () => cleanup()); process.on("SIGINT", () => cleanup()); -} +} \ No newline at end of file diff --git a/server/routers/gerbil/receiveBandwidth.ts b/server/routers/gerbil/receiveBandwidth.ts index dbd687a15..098a1b558 100644 --- a/server/routers/gerbil/receiveBandwidth.ts +++ b/server/routers/gerbil/receiveBandwidth.ts @@ -1,5 +1,5 @@ import { Request, Response, NextFunction } from "express"; -import { eq, and, lt, inArray, sql } from "drizzle-orm"; +import { eq, sql } from "drizzle-orm"; import { sites } from "@server/db"; import { db } from "@server/db"; import logger from "@server/logger"; @@ -11,19 +11,31 @@ import { FeatureId } from "@server/lib/billing/features"; import { checkExitNodeOrg } from "#dynamic/lib/exitNodes"; import { build } from "@server/build"; -// Track sites that are already offline to avoid unnecessary queries -const offlineSites = new Set(); - -// Retry configuration for deadlock handling -const MAX_RETRIES = 3; -const BASE_DELAY_MS = 50; - interface PeerBandwidth { publicKey: string; bytesIn: number; bytesOut: number; } +interface AccumulatorEntry { + bytesIn: number; + bytesOut: number; + /** Present when the update came through a remote exit node. */ + exitNodeId?: number; + /** Whether to record egress usage for billing purposes. */ + calcUsage: boolean; +} + +// Retry configuration for deadlock handling +const MAX_RETRIES = 3; +const BASE_DELAY_MS = 50; + +// How often to flush accumulated bandwidth data to the database +const FLUSH_INTERVAL_MS = 30_000; // 30 seconds + +// In-memory accumulator: publicKey -> AccumulatorEntry +let accumulator = new Map(); + /** * Check if an error is a deadlock error */ @@ -63,6 +75,220 @@ async function withDeadlockRetry( } } +/** + * Flush all accumulated site bandwidth data to the database. + * + * Swaps out the accumulator before writing so that any bandwidth messages + * received during the flush are captured in the new accumulator rather than + * being lost or causing contention. Entries that fail to write are re-queued + * back into the accumulator so they will be retried on the next flush. + * + * This function is exported so that the application's graceful-shutdown + * cleanup handler can call it before the process exits. + */ +export async function flushSiteBandwidthToDb(): Promise { + if (accumulator.size === 0) { + return; + } + + // Atomically swap out the accumulator so new data keeps flowing in + // while we write the snapshot to the database. + const snapshot = accumulator; + accumulator = new Map(); + + const currentTime = new Date().toISOString(); + + // Sort by publicKey for consistent lock ordering across concurrent + // writers — deadlock-prevention strategy. + const sortedEntries = [...snapshot.entries()].sort(([a], [b]) => + a.localeCompare(b) + ); + + logger.debug( + `Flushing accumulated bandwidth data for ${sortedEntries.length} site(s) to the database` + ); + + // Aggregate billing usage by org, collected during the DB update loop. + const orgUsageMap = new Map(); + + for (const [publicKey, { bytesIn, bytesOut, exitNodeId, calcUsage }] of sortedEntries) { + try { + const updatedSite = await withDeadlockRetry(async () => { + const [result] = await db + .update(sites) + .set({ + megabytesOut: sql`COALESCE(${sites.megabytesOut}, 0) + ${bytesIn}`, + megabytesIn: sql`COALESCE(${sites.megabytesIn}, 0) + ${bytesOut}`, + lastBandwidthUpdate: currentTime + }) + .where(eq(sites.pubKey, publicKey)) + .returning({ + orgId: sites.orgId, + siteId: sites.siteId + }); + return result; + }, `flush bandwidth for site ${publicKey}`); + + if (updatedSite) { + if (exitNodeId) { + const notAllowed = await checkExitNodeOrg( + exitNodeId, + updatedSite.orgId + ); + if (notAllowed) { + logger.warn( + `Exit node ${exitNodeId} is not allowed for org ${updatedSite.orgId}` + ); + // Skip usage tracking for this site but continue + // processing the rest. + continue; + } + } + + if (calcUsage) { + const totalBandwidth = bytesIn + bytesOut; + const current = orgUsageMap.get(updatedSite.orgId) ?? 0; + orgUsageMap.set(updatedSite.orgId, current + totalBandwidth); + } + } + } catch (error) { + logger.error( + `Failed to flush bandwidth for site ${publicKey}:`, + error + ); + + // Re-queue the failed entry so it is retried on the next flush + // rather than silently dropped. + const existing = accumulator.get(publicKey); + if (existing) { + existing.bytesIn += bytesIn; + existing.bytesOut += bytesOut; + } else { + accumulator.set(publicKey, { + bytesIn, + bytesOut, + exitNodeId, + calcUsage + }); + } + } + } + + // Process billing usage updates outside the site-update loop to keep + // lock scope small and concerns separated. + if (orgUsageMap.size > 0) { + // Sort org IDs for consistent lock ordering. + const sortedOrgIds = [...orgUsageMap.keys()].sort(); + + for (const orgId of sortedOrgIds) { + try { + const totalBandwidth = orgUsageMap.get(orgId)!; + const bandwidthUsage = await usageService.add( + orgId, + FeatureId.EGRESS_DATA_MB, + totalBandwidth + ); + if (bandwidthUsage) { + // Fire-and-forget — don't block the flush on limit checking. + usageService + .checkLimitSet( + orgId, + FeatureId.EGRESS_DATA_MB, + bandwidthUsage + ) + .catch((error: any) => { + logger.error( + `Error checking bandwidth limits for org ${orgId}:`, + error + ); + }); + } + } catch (error) { + logger.error( + `Error processing usage for org ${orgId}:`, + error + ); + // Continue with other orgs. + } + } + } +} + +// --------------------------------------------------------------------------- +// Periodic flush timer +// --------------------------------------------------------------------------- + +const flushTimer = setInterval(async () => { + try { + await flushSiteBandwidthToDb(); + } catch (error) { + logger.error( + "Unexpected error during periodic site bandwidth flush:", + error + ); + } +}, FLUSH_INTERVAL_MS); + +// Allow the process to exit normally even while the timer is pending. +// The graceful-shutdown path (see server/cleanup.ts) will call +// flushSiteBandwidthToDb() explicitly before process.exit(), so no data +// is lost. +flushTimer.unref(); + +// --------------------------------------------------------------------------- +// Public API +// --------------------------------------------------------------------------- + +/** + * Accumulate bandwidth data reported by a gerbil or remote exit node. + * + * Only peers that actually transferred data (bytesIn > 0) are added to the + * accumulator; peers with no activity are silently ignored, which means the + * flush will only write rows that have genuinely changed. + * + * The function is intentionally synchronous in its fast path so that the + * HTTP handler can respond immediately without waiting for any I/O. + */ +export async function updateSiteBandwidth( + bandwidthData: PeerBandwidth[], + calcUsageAndLimits: boolean, + exitNodeId?: number +): Promise { + for (const { publicKey, bytesIn, bytesOut } of bandwidthData) { + // Skip peers that haven't transferred any data — writing zeros to the + // database would be a no-op anyway. + if (bytesIn <= 0 && bytesOut <= 0) { + continue; + } + + const existing = accumulator.get(publicKey); + if (existing) { + existing.bytesIn += bytesIn; + existing.bytesOut += bytesOut; + // Retain the most-recent exitNodeId for this peer. + if (exitNodeId !== undefined) { + existing.exitNodeId = exitNodeId; + } + // Once calcUsage has been requested for a peer, keep it set for + // the lifetime of this flush window. + if (calcUsageAndLimits) { + existing.calcUsage = true; + } + } else { + accumulator.set(publicKey, { + bytesIn, + bytesOut, + exitNodeId, + calcUsage: calcUsageAndLimits + }); + } + } +} + +// --------------------------------------------------------------------------- +// HTTP handler +// --------------------------------------------------------------------------- + export const receiveBandwidth = async ( req: Request, res: Response, @@ -75,7 +301,9 @@ export const receiveBandwidth = async ( throw new Error("Invalid bandwidth data"); } - await updateSiteBandwidth(bandwidthData, build == "saas"); // we are checking the usage on saas only + // Accumulate in memory; the periodic timer (and the shutdown hook) + // will write to the database. + await updateSiteBandwidth(bandwidthData, build == "saas"); return response(res, { data: {}, @@ -93,202 +321,4 @@ export const receiveBandwidth = async ( ) ); } -}; - -export async function updateSiteBandwidth( - bandwidthData: PeerBandwidth[], - calcUsageAndLimits: boolean, - exitNodeId?: number -) { - const currentTime = new Date(); - const oneMinuteAgo = new Date(currentTime.getTime() - 60000); // 1 minute ago - - // Sort bandwidth data by publicKey to ensure consistent lock ordering across all instances - // This is critical for preventing deadlocks when multiple instances update the same sites - const sortedBandwidthData = [...bandwidthData].sort((a, b) => - a.publicKey.localeCompare(b.publicKey) - ); - - // First, handle sites that are actively reporting bandwidth - const activePeers = sortedBandwidthData.filter((peer) => peer.bytesIn > 0); - - // Aggregate usage data by organization (collected outside transaction) - const orgUsageMap = new Map(); - - if (activePeers.length > 0) { - // Remove any active peers from offline tracking since they're sending data - activePeers.forEach((peer) => offlineSites.delete(peer.publicKey)); - - // Update each active site individually with retry logic - // This reduces transaction scope and allows retries per-site - for (const peer of activePeers) { - try { - const updatedSite = await withDeadlockRetry(async () => { - const [result] = await db - .update(sites) - .set({ - megabytesOut: sql`${sites.megabytesOut} + ${peer.bytesIn}`, - megabytesIn: sql`${sites.megabytesIn} + ${peer.bytesOut}`, - lastBandwidthUpdate: currentTime.toISOString(), - online: true - }) - .where(eq(sites.pubKey, peer.publicKey)) - .returning({ - online: sites.online, - orgId: sites.orgId, - siteId: sites.siteId, - lastBandwidthUpdate: sites.lastBandwidthUpdate - }); - return result; - }, `update active site ${peer.publicKey}`); - - if (updatedSite) { - if (exitNodeId) { - const notAllowed = await checkExitNodeOrg( - exitNodeId, - updatedSite.orgId - ); - if (notAllowed) { - logger.warn( - `Exit node ${exitNodeId} is not allowed for org ${updatedSite.orgId}` - ); - // Skip this site but continue processing others - continue; - } - } - - // Aggregate bandwidth usage for the org - const totalBandwidth = peer.bytesIn + peer.bytesOut; - const currentOrgUsage = - orgUsageMap.get(updatedSite.orgId) || 0; - orgUsageMap.set( - updatedSite.orgId, - currentOrgUsage + totalBandwidth - ); - } - } catch (error) { - logger.error( - `Failed to update bandwidth for site ${peer.publicKey}:`, - error - ); - // Continue with other sites - } - } - } - - // Process usage updates outside of site update transactions - // This separates the concerns and reduces lock contention - if (calcUsageAndLimits && orgUsageMap.size > 0) { - // Sort org IDs to ensure consistent lock ordering - const allOrgIds = [...new Set([...orgUsageMap.keys()])].sort(); - - for (const orgId of allOrgIds) { - try { - // Process bandwidth usage for this org - const totalBandwidth = orgUsageMap.get(orgId); - if (totalBandwidth) { - const bandwidthUsage = await usageService.add( - orgId, - FeatureId.EGRESS_DATA_MB, - totalBandwidth - ); - if (bandwidthUsage) { - // Fire and forget - don't block on limit checking - usageService - .checkLimitSet( - orgId, - FeatureId.EGRESS_DATA_MB, - bandwidthUsage - ) - .catch((error: any) => { - logger.error( - `Error checking bandwidth limits for org ${orgId}:`, - error - ); - }); - } - } - } catch (error) { - logger.error(`Error processing usage for org ${orgId}:`, error); - // Continue with other orgs - } - } - } - - // Handle sites that reported zero bandwidth but need online status updated - const zeroBandwidthPeers = sortedBandwidthData.filter( - (peer) => peer.bytesIn === 0 && !offlineSites.has(peer.publicKey) - ); - - if (zeroBandwidthPeers.length > 0) { - // Fetch all zero bandwidth sites in one query - const zeroBandwidthSites = await db - .select() - .from(sites) - .where( - inArray( - sites.pubKey, - zeroBandwidthPeers.map((p) => p.publicKey) - ) - ); - - // Sort by siteId to ensure consistent lock ordering - const sortedZeroBandwidthSites = zeroBandwidthSites.sort( - (a, b) => a.siteId - b.siteId - ); - - for (const site of sortedZeroBandwidthSites) { - let newOnlineStatus = site.online; - - // Check if site should go offline based on last bandwidth update WITH DATA - if (site.lastBandwidthUpdate) { - const lastUpdateWithData = new Date(site.lastBandwidthUpdate); - if (lastUpdateWithData < oneMinuteAgo) { - newOnlineStatus = false; - } - } else { - // No previous data update recorded, set to offline - newOnlineStatus = false; - } - - // Only update online status if it changed - if (site.online !== newOnlineStatus) { - try { - const updatedSite = await withDeadlockRetry(async () => { - const [result] = await db - .update(sites) - .set({ - online: newOnlineStatus - }) - .where(eq(sites.siteId, site.siteId)) - .returning(); - return result; - }, `update offline status for site ${site.siteId}`); - - if (updatedSite && exitNodeId) { - const notAllowed = await checkExitNodeOrg( - exitNodeId, - updatedSite.orgId - ); - if (notAllowed) { - logger.warn( - `Exit node ${exitNodeId} is not allowed for org ${updatedSite.orgId}` - ); - } - } - - // If site went offline, add it to our tracking set - if (!newOnlineStatus && site.pubKey) { - offlineSites.add(site.pubKey); - } - } catch (error) { - logger.error( - `Failed to update offline status for site ${site.siteId}:`, - error - ); - // Continue with other sites - } - } - } - } -} +}; \ No newline at end of file diff --git a/server/routers/newt/handleReceiveBandwidthMessage.ts b/server/routers/newt/handleReceiveBandwidthMessage.ts index eb930e682..f086333e7 100644 --- a/server/routers/newt/handleReceiveBandwidthMessage.ts +++ b/server/routers/newt/handleReceiveBandwidthMessage.ts @@ -10,10 +10,21 @@ interface PeerBandwidth { bytesOut: number; } +interface BandwidthAccumulator { + bytesIn: number; + bytesOut: number; +} + // Retry configuration for deadlock handling const MAX_RETRIES = 3; const BASE_DELAY_MS = 50; +// How often to flush accumulated bandwidth data to the database +const FLUSH_INTERVAL_MS = 120_000; // 120 seconds + +// In-memory accumulator: publicKey -> { bytesIn, bytesOut } +let accumulator = new Map(); + /** * Check if an error is a deadlock error */ @@ -53,6 +64,90 @@ async function withDeadlockRetry( } } +/** + * Flush all accumulated bandwidth data to the database. + * + * Swaps out the accumulator before writing so that any bandwidth messages + * received during the flush are captured in the new accumulator rather than + * being lost or causing contention. Entries that fail to write are re-queued + * back into the accumulator so they will be retried on the next flush. + * + * This function is exported so that the application's graceful-shutdown + * cleanup handler can call it before the process exits. + */ +export async function flushBandwidthToDb(): Promise { + if (accumulator.size === 0) { + return; + } + + // Atomically swap out the accumulator so new data keeps flowing in + // while we write the snapshot to the database. + const snapshot = accumulator; + accumulator = new Map(); + + const currentTime = new Date().toISOString(); + + // Sort by publicKey for consistent lock ordering across concurrent + // writers — this is the same deadlock-prevention strategy used in the + // original per-message implementation. + const sortedEntries = [...snapshot.entries()].sort(([a], [b]) => + a.localeCompare(b) + ); + + logger.debug( + `Flushing accumulated bandwidth data for ${sortedEntries.length} client(s) to the database` + ); + + for (const [publicKey, { bytesIn, bytesOut }] of sortedEntries) { + try { + await withDeadlockRetry(async () => { + // Use atomic SQL increment to avoid the SELECT-then-UPDATE + // anti-pattern and the races it would introduce. + await db + .update(clients) + .set({ + // Note: bytesIn from peer goes to megabytesOut (data + // sent to client) and bytesOut from peer goes to + // megabytesIn (data received from client). + megabytesOut: sql`COALESCE(${clients.megabytesOut}, 0) + ${bytesIn}`, + megabytesIn: sql`COALESCE(${clients.megabytesIn}, 0) + ${bytesOut}`, + lastBandwidthUpdate: currentTime + }) + .where(eq(clients.pubKey, publicKey)); + }, `flush bandwidth for client ${publicKey}`); + } catch (error) { + logger.error( + `Failed to flush bandwidth for client ${publicKey}:`, + error + ); + + // Re-queue the failed entry so it is retried on the next flush + // rather than silently dropped. + const existing = accumulator.get(publicKey); + if (existing) { + existing.bytesIn += bytesIn; + existing.bytesOut += bytesOut; + } else { + accumulator.set(publicKey, { bytesIn, bytesOut }); + } + } + } +} + +const flushTimer = setInterval(async () => { + try { + await flushBandwidthToDb(); + } catch (error) { + logger.error("Unexpected error during periodic bandwidth flush:", error); + } +}, FLUSH_INTERVAL_MS); + +// Calling unref() means this timer will not keep the Node.js event loop alive +// on its own — the process can still exit normally when there is no other work +// left. The graceful-shutdown path (see server/cleanup.ts) will call +// flushBandwidthToDb() explicitly before process.exit(), so no data is lost. +flushTimer.unref(); + export const handleReceiveBandwidthMessage: MessageHandler = async ( context ) => { @@ -69,40 +164,21 @@ export const handleReceiveBandwidthMessage: MessageHandler = async ( throw new Error("Invalid bandwidth data"); } - // Sort bandwidth data by publicKey to ensure consistent lock ordering across all instances - // This is critical for preventing deadlocks when multiple instances update the same clients - const sortedBandwidthData = [...bandwidthData].sort((a, b) => - a.publicKey.localeCompare(b.publicKey) - ); + // Accumulate the incoming data in memory; the periodic timer (and the + // shutdown hook) will take care of writing it to the database. + for (const { publicKey, bytesIn, bytesOut } of bandwidthData) { + // Skip peers that haven't transferred any data — writing zeros to the + // database would be a no-op anyway. + if (bytesIn <= 0 && bytesOut <= 0) { + continue; + } - const currentTime = new Date().toISOString(); - - // Update each client individually with retry logic - // This reduces transaction scope and allows retries per-client - for (const peer of sortedBandwidthData) { - const { publicKey, bytesIn, bytesOut } = peer; - - try { - await withDeadlockRetry(async () => { - // Use atomic SQL increment to avoid SELECT then UPDATE pattern - // This eliminates the need to read the current value first - await db - .update(clients) - .set({ - // Note: bytesIn from peer goes to megabytesOut (data sent to client) - // and bytesOut from peer goes to megabytesIn (data received from client) - megabytesOut: sql`COALESCE(${clients.megabytesOut}, 0) + ${bytesIn}`, - megabytesIn: sql`COALESCE(${clients.megabytesIn}, 0) + ${bytesOut}`, - lastBandwidthUpdate: currentTime - }) - .where(eq(clients.pubKey, publicKey)); - }, `update client bandwidth ${publicKey}`); - } catch (error) { - logger.error( - `Failed to update bandwidth for client ${publicKey}:`, - error - ); - // Continue with other clients even if one fails + const existing = accumulator.get(publicKey); + if (existing) { + existing.bytesIn += bytesIn; + existing.bytesOut += bytesOut; + } else { + accumulator.set(publicKey, { bytesIn, bytesOut }); } } }; From 1a43f1ef4bb1454c1bc60a1bf2d2dc1c45ae6688 Mon Sep 17 00:00:00 2001 From: Owen Date: Sat, 14 Mar 2026 11:59:20 -0700 Subject: [PATCH 44/50] Handle newt online offline with websocket --- server/db/pg/schema/schema.ts | 1 + server/db/sqlite/schema/schema.ts | 1 + server/private/routers/ws/ws.ts | 28 ++- server/routers/newt/handleNewtPingMessage.ts | 197 ++++++++++--------- server/routers/ws/messageHandlers.ts | 4 +- server/routers/ws/ws.ts | 27 ++- 6 files changed, 159 insertions(+), 99 deletions(-) diff --git a/server/db/pg/schema/schema.ts b/server/db/pg/schema/schema.ts index 2c98fd323..b93c21fd6 100644 --- a/server/db/pg/schema/schema.ts +++ b/server/db/pg/schema/schema.ts @@ -89,6 +89,7 @@ export const sites = pgTable("sites", { lastBandwidthUpdate: varchar("lastBandwidthUpdate"), type: varchar("type").notNull(), // "newt" or "wireguard" online: boolean("online").notNull().default(false), + lastPing: integer("lastPing"), address: varchar("address"), endpoint: varchar("endpoint"), publicKey: varchar("publicKey"), diff --git a/server/db/sqlite/schema/schema.ts b/server/db/sqlite/schema/schema.ts index 510d3a1a0..188caac2b 100644 --- a/server/db/sqlite/schema/schema.ts +++ b/server/db/sqlite/schema/schema.ts @@ -90,6 +90,7 @@ export const sites = sqliteTable("sites", { lastBandwidthUpdate: text("lastBandwidthUpdate"), type: text("type").notNull(), // "newt" or "wireguard" online: integer("online", { mode: "boolean" }).notNull().default(false), + lastPing: integer("lastPing"), // exit node stuff that is how to connect to the site when it has a wg server address: text("address"), // this is the address of the wireguard interface in newt diff --git a/server/private/routers/ws/ws.ts b/server/private/routers/ws/ws.ts index f10df2863..eec9cfe89 100644 --- a/server/private/routers/ws/ws.ts +++ b/server/private/routers/ws/ws.ts @@ -25,7 +25,8 @@ import { OlmSession, RemoteExitNode, RemoteExitNodeSession, - remoteExitNodes + remoteExitNodes, + sites } from "@server/db"; import { eq } from "drizzle-orm"; import { db } from "@server/db"; @@ -846,6 +847,31 @@ const setupConnection = async ( ); }); + // Handle WebSocket protocol-level pings from older newt clients that do + // not send application-level "newt/ping" messages. Update the site's + // online state and lastPing timestamp so the offline checker treats them + // the same as modern newt clients. + if (clientType === "newt") { + const newtClient = client as Newt; + ws.on("ping", async () => { + if (!newtClient.siteId) return; + try { + await db + .update(sites) + .set({ + online: true, + lastPing: Math.floor(Date.now() / 1000) + }) + .where(eq(sites.siteId, newtClient.siteId)); + } catch (error) { + logger.error( + "Error updating newt site online state on WS ping", + { error } + ); + } + }); + } + ws.on("error", (error: Error) => { logger.error( `WebSocket error for ${clientType.toUpperCase()} ID ${clientId}:`, diff --git a/server/routers/newt/handleNewtPingMessage.ts b/server/routers/newt/handleNewtPingMessage.ts index dc9aacdd9..319647b83 100644 --- a/server/routers/newt/handleNewtPingMessage.ts +++ b/server/routers/newt/handleNewtPingMessage.ts @@ -1,105 +1,107 @@ -import { db, sites } from "@server/db"; -import { disconnectClient, getClientConfigVersion } from "#dynamic/routers/ws"; +import { db, newts, sites } from "@server/db"; +import { hasActiveConnections, getClientConfigVersion } from "#dynamic/routers/ws"; import { MessageHandler } from "@server/routers/ws"; -import { clients, Newt } from "@server/db"; +import { Newt } from "@server/db"; import { eq, lt, isNull, and, or } from "drizzle-orm"; import logger from "@server/logger"; -import { validateSessionToken } from "@server/auth/sessions/app"; -import { checkOrgAccessPolicy } from "#dynamic/lib/checkOrgAccessPolicy"; -import { sendTerminateClient } from "../client/terminate"; -import { encodeHexLowerCase } from "@oslojs/encoding"; -import { sha256 } from "@oslojs/crypto/sha2"; import { sendNewtSyncMessage } from "./sync"; // Track if the offline checker interval is running -// let offlineCheckerInterval: NodeJS.Timeout | null = null; -// const OFFLINE_CHECK_INTERVAL = 30 * 1000; // Check every 30 seconds -// const OFFLINE_THRESHOLD_MS = 2 * 60 * 1000; // 2 minutes +let offlineCheckerInterval: NodeJS.Timeout | null = null; +const OFFLINE_CHECK_INTERVAL = 30 * 1000; // Check every 30 seconds +const OFFLINE_THRESHOLD_MS = 2 * 60 * 1000; // 2 minutes /** - * Starts the background interval that checks for clients that haven't pinged recently - * and marks them as offline + * Starts the background interval that checks for newt sites that haven't + * pinged recently and marks them as offline. For backward compatibility, + * a site is only marked offline when there is no active WebSocket connection + * either — so older newt versions that don't send pings but remain connected + * continue to be treated as online. */ -// export const startNewtOfflineChecker = (): void => { -// if (offlineCheckerInterval) { -// return; // Already running -// } +export const startNewtOfflineChecker = (): void => { + if (offlineCheckerInterval) { + return; // Already running + } -// offlineCheckerInterval = setInterval(async () => { -// try { -// const twoMinutesAgo = Math.floor( -// (Date.now() - OFFLINE_THRESHOLD_MS) / 1000 -// ); + offlineCheckerInterval = setInterval(async () => { + try { + const twoMinutesAgo = Math.floor( + (Date.now() - OFFLINE_THRESHOLD_MS) / 1000 + ); -// // TODO: WE NEED TO MAKE SURE THIS WORKS WITH DISTRIBUTED NODES ALL DOING THE SAME THING + // Find all online newt-type sites that haven't pinged recently + // (or have never pinged at all). Join newts to obtain the newtId + // needed for the WebSocket connection check. + const staleSites = await db + .select({ + siteId: sites.siteId, + newtId: newts.newtId, + lastPing: sites.lastPing + }) + .from(sites) + .innerJoin(newts, eq(newts.siteId, sites.siteId)) + .where( + and( + eq(sites.online, true), + eq(sites.type, "newt"), + or( + lt(sites.lastPing, twoMinutesAgo), + isNull(sites.lastPing) + ) + ) + ); -// // Find clients that haven't pinged in the last 2 minutes and mark them as offline -// const offlineClients = await db -// .update(clients) -// .set({ online: false }) -// .where( -// and( -// eq(clients.online, true), -// or( -// lt(clients.lastPing, twoMinutesAgo), -// isNull(clients.lastPing) -// ) -// ) -// ) -// .returning(); + for (const staleSite of staleSites) { + // Backward-compatibility check: if the newt still has an + // active WebSocket connection (older clients that don't send + // pings), keep the site online. + const isConnected = await hasActiveConnections(staleSite.newtId); + if (isConnected) { + logger.debug( + `Newt ${staleSite.newtId} has not pinged recently but is still connected via WebSocket — keeping site ${staleSite.siteId} online` + ); + continue; + } -// for (const offlineClient of offlineClients) { -// logger.info( -// `Kicking offline newt client ${offlineClient.clientId} due to inactivity` -// ); + logger.info( + `Marking site ${staleSite.siteId} offline: newt ${staleSite.newtId} has no recent ping and no active WebSocket connection` + ); -// if (!offlineClient.newtId) { -// logger.warn( -// `Offline client ${offlineClient.clientId} has no newtId, cannot disconnect` -// ); -// continue; -// } + await db + .update(sites) + .set({ online: false }) + .where(eq(sites.siteId, staleSite.siteId)); + } + } catch (error) { + logger.error("Error in newt offline checker interval", { error }); + } + }, OFFLINE_CHECK_INTERVAL); -// // Send a disconnect message to the client if connected -// try { -// await sendTerminateClient( -// offlineClient.clientId, -// offlineClient.newtId -// ); // terminate first -// // wait a moment to ensure the message is sent -// await new Promise((resolve) => setTimeout(resolve, 1000)); -// await disconnectClient(offlineClient.newtId); -// } catch (error) { -// logger.error( -// `Error sending disconnect to offline newt ${offlineClient.clientId}`, -// { error } -// ); -// } -// } -// } catch (error) { -// logger.error("Error in offline checker interval", { error }); -// } -// }, OFFLINE_CHECK_INTERVAL); - -// logger.debug("Started offline checker interval"); -// }; + logger.debug("Started newt offline checker interval"); +}; /** - * Stops the background interval that checks for offline clients + * Stops the background interval that checks for offline newt sites. */ -// export const stopNewtOfflineChecker = (): void => { -// if (offlineCheckerInterval) { -// clearInterval(offlineCheckerInterval); -// offlineCheckerInterval = null; -// logger.info("Stopped offline checker interval"); -// } -// }; +export const stopNewtOfflineChecker = (): void => { + if (offlineCheckerInterval) { + clearInterval(offlineCheckerInterval); + offlineCheckerInterval = null; + logger.info("Stopped newt offline checker interval"); + } +}; /** - * Handles ping messages from clients and responds with pong + * Handles ping messages from newt clients. + * + * On each ping: + * - Marks the associated site as online. + * - Records the current timestamp as the newt's last-ping time. + * - Triggers a config sync if the newt is running an outdated config version. + * - Responds with a pong message. */ export const handleNewtPingMessage: MessageHandler = async (context) => { - const { message, client: c, sendToClient } = context; + const { message, client: c } = context; const newt = c as Newt; if (!newt) { @@ -112,15 +114,31 @@ export const handleNewtPingMessage: MessageHandler = async (context) => { return; } - // get the version + try { + // Mark the site as online and record the ping timestamp. + await db + .update(sites) + .set({ + online: true, + lastPing: Math.floor(Date.now() / 1000) + }) + .where(eq(sites.siteId, newt.siteId)); + } catch (error) { + logger.error("Error updating online state on newt ping", { error }); + } + + // Check config version and sync if stale. const configVersion = await getClientConfigVersion(newt.newtId); - if (message.configVersion && configVersion != null && configVersion != message.configVersion) { + if ( + message.configVersion != null && + configVersion != null && + configVersion !== message.configVersion + ) { logger.warn( `Newt ping with outdated config version: ${message.configVersion} (current: ${configVersion})` ); - // get the site const [site] = await db .select() .from(sites) @@ -137,19 +155,6 @@ export const handleNewtPingMessage: MessageHandler = async (context) => { await sendNewtSyncMessage(newt, site); } - // try { - // // Update the client's last ping timestamp - // await db - // .update(clients) - // .set({ - // lastPing: Math.floor(Date.now() / 1000), - // online: true - // }) - // .where(eq(clients.clientId, newt.clientId)); - // } catch (error) { - // logger.error("Error handling ping message", { error }); - // } - return { message: { type: "pong", diff --git a/server/routers/ws/messageHandlers.ts b/server/routers/ws/messageHandlers.ts index f041c9d56..25eb578e1 100644 --- a/server/routers/ws/messageHandlers.ts +++ b/server/routers/ws/messageHandlers.ts @@ -6,7 +6,8 @@ import { handleDockerContainersMessage, handleNewtPingRequestMessage, handleApplyBlueprintMessage, - handleNewtPingMessage + handleNewtPingMessage, + startNewtOfflineChecker } from "../newt"; import { handleOlmRegisterMessage, @@ -43,3 +44,4 @@ export const messageHandlers: Record = { }; startOlmOfflineChecker(); // this is to handle the offline check for olms +startNewtOfflineChecker(); // this is to handle the offline check for newts diff --git a/server/routers/ws/ws.ts b/server/routers/ws/ws.ts index c7085fba9..08a7dbd4c 100644 --- a/server/routers/ws/ws.ts +++ b/server/routers/ws/ws.ts @@ -3,7 +3,7 @@ import zlib from "zlib"; import { Server as HttpServer } from "http"; import { WebSocket, WebSocketServer } from "ws"; import { Socket } from "net"; -import { Newt, newts, NewtSession, olms, Olm, OlmSession } from "@server/db"; +import { Newt, newts, NewtSession, olms, Olm, OlmSession, sites } from "@server/db"; import { eq } from "drizzle-orm"; import { db } from "@server/db"; import { validateNewtSessionToken } from "@server/auth/sessions/newt"; @@ -380,6 +380,31 @@ const setupConnection = async ( ); }); + // Handle WebSocket protocol-level pings from older newt clients that do + // not send application-level "newt/ping" messages. Update the site's + // online state and lastPing timestamp so the offline checker treats them + // the same as modern newt clients. + if (clientType === "newt") { + const newtClient = client as Newt; + ws.on("ping", async () => { + if (!newtClient.siteId) return; + try { + await db + .update(sites) + .set({ + online: true, + lastPing: Math.floor(Date.now() / 1000) + }) + .where(eq(sites.siteId, newtClient.siteId)); + } catch (error) { + logger.error( + "Error updating newt site online state on WS ping", + { error } + ); + } + }); + } + ws.on("error", (error: Error) => { logger.error( `WebSocket error for ${clientType.toUpperCase()} ID ${clientId}:`, From 86bba494febff752299cc52fc507b2e9f65c10f9 Mon Sep 17 00:00:00 2001 From: Owen Date: Sat, 14 Mar 2026 16:03:43 -0700 Subject: [PATCH 45/50] Disable intervals in saas --- server/lib/cleanupLogs.ts | 4 +++ server/private/routers/ws/messageHandlers.ts | 5 ++- .../newt/handleNewtDisconnectingMessage.ts | 34 +++++++++++++++++++ server/routers/newt/index.ts | 1 + .../olm/handleOlmDisconnectingMessage.ts | 2 +- server/routers/ws/messageHandlers.ts | 15 +++++--- 6 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 server/routers/newt/handleNewtDisconnectingMessage.ts diff --git a/server/lib/cleanupLogs.ts b/server/lib/cleanupLogs.ts index 96a589ee4..8eb4ca77f 100644 --- a/server/lib/cleanupLogs.ts +++ b/server/lib/cleanupLogs.ts @@ -4,8 +4,12 @@ import { cleanUpOldLogs as cleanUpOldActionLogs } from "#dynamic/middlewares/log import { cleanUpOldLogs as cleanUpOldRequestLogs } from "@server/routers/badger/logRequestAudit"; import { gt, or } from "drizzle-orm"; import { cleanUpOldFingerprintSnapshots } from "@server/routers/olm/fingerprintingUtils"; +import { build } from "@server/build"; export function initLogCleanupInterval() { + if (build == "saas") { // skip log cleanup for saas builds + return null; + } return setInterval( async () => { const orgsToClean = await db diff --git a/server/private/routers/ws/messageHandlers.ts b/server/private/routers/ws/messageHandlers.ts index 5a6c85cff..d388ce40a 100644 --- a/server/private/routers/ws/messageHandlers.ts +++ b/server/private/routers/ws/messageHandlers.ts @@ -17,10 +17,13 @@ import { startRemoteExitNodeOfflineChecker } from "#private/routers/remoteExitNode"; import { MessageHandler } from "@server/routers/ws"; +import { build } from "@server/build"; export const messageHandlers: Record = { "remoteExitNode/register": handleRemoteExitNodeRegisterMessage, "remoteExitNode/ping": handleRemoteExitNodePingMessage }; -startRemoteExitNodeOfflineChecker(); // this is to handle the offline check for remote exit nodes +if (build != "saas") { + startRemoteExitNodeOfflineChecker(); // this is to handle the offline check for remote exit nodes +} diff --git a/server/routers/newt/handleNewtDisconnectingMessage.ts b/server/routers/newt/handleNewtDisconnectingMessage.ts new file mode 100644 index 000000000..e23710616 --- /dev/null +++ b/server/routers/newt/handleNewtDisconnectingMessage.ts @@ -0,0 +1,34 @@ +import { MessageHandler } from "@server/routers/ws"; +import { db, Newt, sites } from "@server/db"; +import { eq } from "drizzle-orm"; +import logger from "@server/logger"; + +/** + * Handles disconnecting messages from sites to show disconnected in the ui + */ +export const handleNewtDisconnectingMessage: MessageHandler = async (context) => { + const { message, client: c, sendToClient } = context; + const newt = c as Newt; + + if (!newt) { + logger.warn("Newt not found"); + return; + } + + if (!newt.siteId) { + logger.warn("Newt has no client ID!"); + return; + } + + try { + // Update the client's last ping timestamp + await db + .update(sites) + .set({ + online: false + }) + .where(eq(sites.siteId, sites.siteId)); + } catch (error) { + logger.error("Error handling disconnecting message", { error }); + } +}; diff --git a/server/routers/newt/index.ts b/server/routers/newt/index.ts index 8ff1b61ae..f31cd753b 100644 --- a/server/routers/newt/index.ts +++ b/server/routers/newt/index.ts @@ -7,3 +7,4 @@ export * from "./handleSocketMessages"; export * from "./handleNewtPingRequestMessage"; export * from "./handleApplyBlueprintMessage"; export * from "./handleNewtPingMessage"; +export * from "./handleNewtDisconnectingMessage"; diff --git a/server/routers/olm/handleOlmDisconnectingMessage.ts b/server/routers/olm/handleOlmDisconnectingMessage.ts index 2ddd5e515..ecd101724 100644 --- a/server/routers/olm/handleOlmDisconnectingMessage.ts +++ b/server/routers/olm/handleOlmDisconnectingMessage.ts @@ -6,7 +6,7 @@ import logger from "@server/logger"; /** * Handles disconnecting messages from clients to show disconnected in the ui */ -export const handleOlmDisconnecingMessage: MessageHandler = async (context) => { +export const handleOlmDisconnectingMessage: MessageHandler = async (context) => { const { message, client: c, sendToClient } = context; const olm = c as Olm; diff --git a/server/routers/ws/messageHandlers.ts b/server/routers/ws/messageHandlers.ts index 25eb578e1..628caafd5 100644 --- a/server/routers/ws/messageHandlers.ts +++ b/server/routers/ws/messageHandlers.ts @@ -1,3 +1,4 @@ +import { build } from "@server/build"; import { handleNewtRegisterMessage, handleReceiveBandwidthMessage, @@ -7,7 +8,8 @@ import { handleNewtPingRequestMessage, handleApplyBlueprintMessage, handleNewtPingMessage, - startNewtOfflineChecker + startNewtOfflineChecker, + handleNewtDisconnectingMessage } from "../newt"; import { handleOlmRegisterMessage, @@ -16,7 +18,7 @@ import { startOlmOfflineChecker, handleOlmServerPeerAddMessage, handleOlmUnRelayMessage, - handleOlmDisconnecingMessage, + handleOlmDisconnectingMessage, handleOlmServerInitAddPeerHandshake } from "../olm"; import { handleHealthcheckStatusMessage } from "../target"; @@ -30,7 +32,8 @@ export const messageHandlers: Record = { "olm/wg/relay": handleOlmRelayMessage, "olm/wg/unrelay": handleOlmUnRelayMessage, "olm/ping": handleOlmPingMessage, - "olm/disconnecting": handleOlmDisconnecingMessage, + "olm/disconnecting": handleOlmDisconnectingMessage, + "newt/disconnecting": handleNewtDisconnectingMessage, "newt/ping": handleNewtPingMessage, "newt/wg/register": handleNewtRegisterMessage, "newt/wg/get-config": handleGetConfigMessage, @@ -43,5 +46,7 @@ export const messageHandlers: Record = { "ws/round-trip/complete": handleRoundTripMessage }; -startOlmOfflineChecker(); // this is to handle the offline check for olms -startNewtOfflineChecker(); // this is to handle the offline check for newts +if (build != "saas") { + startOlmOfflineChecker(); // this is to handle the offline check for olms + startNewtOfflineChecker(); // this is to handle the offline check for newts +} From 6d5f969798ce5c1839265672956cfae084267e2f Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 15 Mar 2026 22:01:39 -0700 Subject: [PATCH 46/50] Fix jit on by default --- server/routers/olm/handleOlmRegisterMessage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/routers/olm/handleOlmRegisterMessage.ts b/server/routers/olm/handleOlmRegisterMessage.ts index 065aeeaa6..5439245c4 100644 --- a/server/routers/olm/handleOlmRegisterMessage.ts +++ b/server/routers/olm/handleOlmRegisterMessage.ts @@ -227,7 +227,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { // Prepare an array to store site configurations logger.debug(`Found ${sitesCount} sites for client ${client.clientId}`); - let jitMode = true; + let jitMode = false; if (sitesCount > 250 && build == "saas") { // THIS IS THE MAX ON THE BUSINESS TIER // we have too many sites From 23d3345ab9fd9adde207ba2af08beac45dd4791f Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 16 Mar 2026 14:37:27 -0700 Subject: [PATCH 47/50] Reduce writes --- server/private/routers/ws/ws.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/server/private/routers/ws/ws.ts b/server/private/routers/ws/ws.ts index eec9cfe89..4bfda5da8 100644 --- a/server/private/routers/ws/ws.ts +++ b/server/private/routers/ws/ws.ts @@ -197,6 +197,12 @@ const connectedClients: Map = new Map(); // Config version tracking map (local to this node, resets on server restart) const clientConfigVersions: Map = new Map(); +// Tracks the last Unix timestamp (seconds) at which a ping was flushed to the +// DB for a given siteId. Resets on server restart which is fine – the first +// ping after startup will always write, re-establishing the online state. +const lastPingDbWrite: Map = new Map(); +const PING_DB_WRITE_INTERVAL = 45; // seconds + // Recovery tracking let isRedisRecoveryInProgress = false; @@ -855,12 +861,16 @@ const setupConnection = async ( const newtClient = client as Newt; ws.on("ping", async () => { if (!newtClient.siteId) return; + const now = Math.floor(Date.now() / 1000); + const lastWrite = lastPingDbWrite.get(newtClient.siteId) ?? 0; + if (now - lastWrite < PING_DB_WRITE_INTERVAL) return; + lastPingDbWrite.set(newtClient.siteId, now); try { await db .update(sites) .set({ online: true, - lastPing: Math.floor(Date.now() / 1000) + lastPing: now }) .where(eq(sites.siteId, newtClient.siteId)); } catch (error) { From bab09dff9539d53ea76ca58a6d1d2ac28f55302d Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 16 Mar 2026 15:33:21 -0700 Subject: [PATCH 48/50] Add better metadata to ssh --- server/private/routers/external.ts | 2 +- server/private/routers/ssh/signSshKey.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/server/private/routers/external.ts b/server/private/routers/external.ts index bd4d232de..df8ea8cbb 100644 --- a/server/private/routers/external.ts +++ b/server/private/routers/external.ts @@ -515,6 +515,6 @@ authenticated.post( verifyOrgAccess, verifyLimits, verifyUserHasAction(ActionsEnum.signSshKey), - logActionAudit(ActionsEnum.signSshKey), + // logActionAudit(ActionsEnum.signSshKey), // it is handled inside of the function below so we can include more metadata ssh.signSshKey ); diff --git a/server/private/routers/ssh/signSshKey.ts b/server/private/routers/ssh/signSshKey.ts index e70951812..5cffb4a34 100644 --- a/server/private/routers/ssh/signSshKey.ts +++ b/server/private/routers/ssh/signSshKey.ts @@ -14,7 +14,9 @@ import { Request, Response, NextFunction } from "express"; import { z } from "zod"; import { + actionAuditLog, db, + logsDb, newts, roles, roundTripMessageTracker, @@ -34,6 +36,7 @@ import { canUserAccessSiteResource } from "@server/auth/canUserAccessSiteResourc import { signPublicKey, getOrgCAKeys } from "@server/lib/sshCA"; import config from "@server/lib/config"; import { sendToClient } from "#private/routers/ws"; +import { ActionsEnum } from "@server/auth/actions"; const paramsSchema = z.strictObject({ orgId: z.string().nonempty() @@ -446,6 +449,20 @@ export async function signSshKey( sshHost = resource.destination; } + await logsDb.insert(actionAuditLog).values({ + timestamp: Math.floor(Date.now() / 1000), + orgId: orgId, + actorType: "user", + actor: req.user?.username ?? "", + actorId: req.user?.userId ?? "", + action: ActionsEnum.signSshKey, + metadata: JSON.stringify({ + resourceId: resource.siteResourceId, + resource: resource.name, + siteId: resource.siteId, + }) + }); + return response(res, { data: { certificate: cert.certificate, From ea41fcc5662324ef4ada3f83f702738e2bc02527 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 16 Mar 2026 17:12:37 -0700 Subject: [PATCH 49/50] Also update lastPing for legacy --- server/routers/gerbil/receiveBandwidth.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/routers/gerbil/receiveBandwidth.ts b/server/routers/gerbil/receiveBandwidth.ts index 098a1b558..e06a6d5d0 100644 --- a/server/routers/gerbil/receiveBandwidth.ts +++ b/server/routers/gerbil/receiveBandwidth.ts @@ -97,6 +97,7 @@ export async function flushSiteBandwidthToDb(): Promise { accumulator = new Map(); const currentTime = new Date().toISOString(); + const currentTimeEpochSeconds = Math.floor(new Date().getTime() / 1000); // Sort by publicKey for consistent lock ordering across concurrent // writers — deadlock-prevention strategy. @@ -119,7 +120,8 @@ export async function flushSiteBandwidthToDb(): Promise { .set({ megabytesOut: sql`COALESCE(${sites.megabytesOut}, 0) + ${bytesIn}`, megabytesIn: sql`COALESCE(${sites.megabytesIn}, 0) + ${bytesOut}`, - lastBandwidthUpdate: currentTime + lastBandwidthUpdate: currentTime, + lastPing: currentTimeEpochSeconds }) .where(eq(sites.pubKey, publicKey)) .returning({ @@ -321,4 +323,4 @@ export const receiveBandwidth = async ( ) ); } -}; \ No newline at end of file +}; From e14e15fcbb00b976383b1efc9fbc4f8d2fe25fc7 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 16 Mar 2026 17:47:06 -0700 Subject: [PATCH 50/50] Revert: Also update lastPing for legacy --- server/routers/gerbil/receiveBandwidth.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/routers/gerbil/receiveBandwidth.ts b/server/routers/gerbil/receiveBandwidth.ts index e06a6d5d0..b73ce986d 100644 --- a/server/routers/gerbil/receiveBandwidth.ts +++ b/server/routers/gerbil/receiveBandwidth.ts @@ -97,7 +97,6 @@ export async function flushSiteBandwidthToDb(): Promise { accumulator = new Map(); const currentTime = new Date().toISOString(); - const currentTimeEpochSeconds = Math.floor(new Date().getTime() / 1000); // Sort by publicKey for consistent lock ordering across concurrent // writers — deadlock-prevention strategy. @@ -121,7 +120,6 @@ export async function flushSiteBandwidthToDb(): Promise { megabytesOut: sql`COALESCE(${sites.megabytesOut}, 0) + ${bytesIn}`, megabytesIn: sql`COALESCE(${sites.megabytesIn}, 0) + ${bytesOut}`, lastBandwidthUpdate: currentTime, - lastPing: currentTimeEpochSeconds }) .where(eq(sites.pubKey, publicKey)) .returning({