diff --git a/docker-compose.yml b/docker-compose.yml index 1b166ef..ce19a47 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -122,7 +122,7 @@ services: - JWT_SECRET=KRUGKIDROVUWG2ZAMJZG653OEBTG66BANJ2W24DTEBXXMZLSEB2GQZJANRQXU6JA - DATABASE_DIR=/volumes/database - PROVIDER_FILE=/extra/providers.toml - + - SESSION_MANAGER=${SESSION_MANAGER} ############### # USER # diff --git a/frontend/package.json b/frontend/package.json index 9e51cb2..04bd252 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,7 @@ "devDependencies": { "@types/js-cookie": "^3.0.6", "typescript": "~5.9.3", - "vite": "^7.2.4", + "vite": "^7.2.6", "vite-tsconfig-paths": "^5.1.4" }, "dependencies": { diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index a490db1..6addf30 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@tailwindcss/vite': specifier: ^4.1.17 - version: 4.1.17(vite@7.2.4(jiti@2.6.1)(lightningcss@1.30.2)) + version: 4.1.17(vite@7.2.6(jiti@2.6.1)(lightningcss@1.30.2)) js-cookie: specifier: ^3.0.5 version: 3.0.5 @@ -31,11 +31,11 @@ importers: specifier: ~5.9.3 version: 5.9.3 vite: - specifier: ^7.2.4 - version: 7.2.4(jiti@2.6.1)(lightningcss@1.30.2) + specifier: ^7.2.6 + version: 7.2.6(jiti@2.6.1)(lightningcss@1.30.2) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.4(jiti@2.6.1)(lightningcss@1.30.2)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.6(jiti@2.6.1)(lightningcss@1.30.2)) packages: @@ -635,8 +635,8 @@ packages: vite: optional: true - vite@7.2.4: - resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} + vite@7.2.6: + resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -919,12 +919,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.17 '@tailwindcss/oxide-win32-x64-msvc': 4.1.17 - '@tailwindcss/vite@4.1.17(vite@7.2.4(jiti@2.6.1)(lightningcss@1.30.2))': + '@tailwindcss/vite@4.1.17(vite@7.2.6(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@tailwindcss/node': 4.1.17 '@tailwindcss/oxide': 4.1.17 tailwindcss: 4.1.17 - vite: 7.2.4(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.2.6(jiti@2.6.1)(lightningcss@1.30.2) '@types/estree@1.0.8': {} @@ -1139,18 +1139,18 @@ snapshots: typescript@5.9.3: {} - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.4(jiti@2.6.1)(lightningcss@1.30.2)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.6(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.2.4(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.2.6(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - supports-color - typescript - vite@7.2.4(jiti@2.6.1)(lightningcss@1.30.2): + vite@7.2.6(jiti@2.6.1)(lightningcss@1.30.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) diff --git a/frontend/src/@types/dom.d.ts b/frontend/src/@types/dom.d.ts index 5cbf23c..1c35dd9 100644 --- a/frontend/src/@types/dom.d.ts +++ b/frontend/src/@types/dom.d.ts @@ -9,4 +9,6 @@ declare global { dispatchEvent(ev: CustomEventMap[K]): void; } } + + export { }; //keep that for TS compiler. diff --git a/frontend/src/api/generated/.openapi-generator/FILES b/frontend/src/api/generated/.openapi-generator/FILES index b02736b..af12e66 100644 --- a/frontend/src/api/generated/.openapi-generator/FILES +++ b/frontend/src/api/generated/.openapi-generator/FILES @@ -2,7 +2,6 @@ apis/OpenapiOtherApi.ts apis/index.ts index.ts models/ChatTest200Response.ts -models/ChatTest500Response.ts models/DisableOtp200Response.ts models/DisableOtp401Response.ts models/DisableOtp500Response.ts diff --git a/frontend/src/api/generated/apis/OpenapiOtherApi.ts b/frontend/src/api/generated/apis/OpenapiOtherApi.ts index f03d19e..fda4f60 100644 --- a/frontend/src/api/generated/apis/OpenapiOtherApi.ts +++ b/frontend/src/api/generated/apis/OpenapiOtherApi.ts @@ -16,7 +16,6 @@ import * as runtime from '../runtime'; import type { ChatTest200Response, - ChatTest500Response, DisableOtp200Response, DisableOtp401Response, DisableOtp500Response, @@ -50,8 +49,6 @@ import type { import { ChatTest200ResponseFromJSON, ChatTest200ResponseToJSON, - ChatTest500ResponseFromJSON, - ChatTest500ResponseToJSON, DisableOtp200ResponseFromJSON, DisableOtp200ResponseToJSON, DisableOtp401ResponseFromJSON, @@ -135,7 +132,7 @@ export class OpenapiOtherApi extends runtime.BaseAPI { /** */ - async chatTestRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + async chatTestRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -162,19 +159,15 @@ export class OpenapiOtherApi extends runtime.BaseAPI { // Object response for status 401 return new runtime.JSONApiResponse(response, (jsonValue) => StatusOtp401ResponseFromJSON(jsonValue)); } - if (response.status === 500) { - // Object response for status 500 - return new runtime.JSONApiResponse(response, (jsonValue) => ChatTest500ResponseFromJSON(jsonValue)); - } // CHANGED: Throw error if status code is not handled by any of the defined responses // This ensures all code paths return a value and provides clear error messages for unexpected status codes // Only throw if responses were defined but none matched the actual status code - throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 401, 500`); + throw new runtime.ResponseError(response, `Unexpected status code: ${response.status}. Expected one of: 200, 401`); } /** */ - async chatTest(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + async chatTest(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { const response = await this.chatTestRaw(initOverrides); return await response.value(); } diff --git a/frontend/src/api/generated/models/index.ts b/frontend/src/api/generated/models/index.ts index b4d967b..a4059b0 100644 --- a/frontend/src/api/generated/models/index.ts +++ b/frontend/src/api/generated/models/index.ts @@ -1,7 +1,6 @@ /* tslint:disable */ /* eslint-disable */ export * from './ChatTest200Response'; -export * from './ChatTest500Response'; export * from './DisableOtp200Response'; export * from './DisableOtp401Response'; export * from './DisableOtp500Response'; diff --git a/frontend/src/chat/chat.css b/frontend/src/chat/chat.css index d02bc50..eb43dce 100644 --- a/frontend/src/chat/chat.css +++ b/frontend/src/chat/chat.css @@ -1,39 +1,56 @@ @import "tailwindcss"; +@font-face { + font-family: "Nimbus Mono L"; + src: url("/fonts/NimbusMonoL.woff2") format("woff2"); +} .btn-style { @apply - w-[100px] - h-[32px] - border-2 border-black + w-[100px] + h-[32px] + border-1 + border-gray-500 rounded-3xl + bg-gray-500 + text-white + cursor-pointer + shadow-[0_2px_0_0_black] + transition-all hover:bg-blue-200 - active:bg-white - text-black - cursor-pointer; + active:bg-gray-400 + active:translate-y-[1px] + active:shadow-[0_2px_0_0_black]; } .send-btn-style { @apply w-[50px] h-[50px] - border-2 border-black + border-1 + border-gray-500 rounded-3xl hover:bg-blue-200 - active:bg-white - text-black - cursor-pointer; + bg-red-100 + text-red-700 + cursor-pointer + shadow-[0_2px_0_0_black] + transition-all + active:bg-gray-400 + active:translate-y-[1px] + active:shadow-[0_2px_0_0_black];; } - .chatbox-style { @apply - w-[600px] - h-[150px] /* increase height if needed */ - p-[10px] - border-1 border-black - shadow-sm + w-[650px] + h-[300px] /* increase height if needed */ + p-[8px] + border-1 + border-black + shadow-2xl text-left - text-gray-800 + text-gray-700 + bg-white rounded-3xl overflow-y-auto whitespace-pre-line @@ -42,16 +59,43 @@ mx-auto; } +.system-info { + @apply + h-[40px] + bg-gray-200 + text-gray-700 + p-3 + rounded-3xl + mb-2 border + border-gray-200 + text-center + shadow + overflow-y-auto + justify-end /* 👈 forces text to bottom */ + relative; /* needed for overlay */ +} + + +.text-info { + @apply + text-blue-800 + +} + + .chat-window-style { @apply w-[400px] h-[50px] p-[10px] - border-1 border-black + border-1 + border-black shadow-sm + flex-1 rounded-3xl - focus:bg-gray-300 - hover:bg-blue-200 + focus:bg-blue-300 + hover:bg-blue-200 + bg-white text-gray-800; } @@ -62,7 +106,8 @@ flex items-center justify-center - bg-gray-100; + bg-[#43536b]; + } .mainboxDisplay { @@ -72,7 +117,7 @@ left-1/2 -translate-x-1/2 -translate-y-1/2 - bg-white w-[650px] + bg-gray-200 w-[850px] p-6 rounded-xl shadow-2xl text-center z-50; @@ -80,20 +125,59 @@ .mainboxDisplay button { @apply - cursor-pointer; + cursor-pointer +} + +.title { + @apply + text-6xl + font-bold + text-gray-800 +} + +.ping-box { + @apply + w-[150px] + ml-2 border-1 + border-gray-500 + bg-white + rounded-2xl + p-2 + shadow-md + flex flex-col + gap-1 + h-[350px]; +} + +.ping-title { + @apply + text-sm + font-semibold + text-blue-800; +} + +div-buddies-list { + @apply + text-black + whitespace-pre-wrap; + } p { @apply text-black - - - } -.div-test { +div-test { @apply - italic - + text-red-800 + text-right; + +} +div-notlog { + @apply + text-red-800 + text-3xl + text-center; } \ No newline at end of file diff --git a/frontend/src/pages/chat/chat.html b/frontend/src/pages/chat/chat.html index 1e765fc..2882ae5 100644 --- a/frontend/src/pages/chat/chat.html +++ b/frontend/src/pages/chat/chat.html @@ -1,19 +1,42 @@
-
- -

- Chat Box -


- - -

Welcome


-
-
-
- - -
-
-

From this Chat Box you can send messages to other players

-
-
\ No newline at end of file +
+ +

+ ChatterBox +


+ + + + +
System: connecting ...
+
+ + +
+ +
+
+
+ + +
+
+ +
+

Ping Buddies

+
+
+ +
+
+
+
+
+

From this Chat Box you can send messages to other players

+
+ + + + diff --git a/frontend/src/pages/chat/chat.ts b/frontend/src/pages/chat/chat.ts index 7c30261..26dd177 100644 --- a/frontend/src/pages/chat/chat.ts +++ b/frontend/src/pages/chat/chat.ts @@ -4,6 +4,27 @@ import authHtml from './chat.html?raw'; import client from '@app/api' import { getUser, updateUser } from "@app/auth"; import io, { Socket } from 'socket.io-client'; +// import type { ClientMessage } from "@app/@types/dom"; + +const color = { + red: 'color: red;', + green: 'color: green;', + yellow: 'color: orange;', + blue: 'color: blue;', + reset: '', +}; + +export type ClientMessage = { + destination: string; + user: string; + text: string; + SenderWindowID: string; +}; + + +// get the name of the machine used to connect +const machineHostName = window.location.hostname; +console.log('connect to login at %chttps://' + machineHostName + ':8888/app/login',color.yellow); let __socket: Socket | undefined = undefined; document.addEventListener('ft:pageChange', () => { @@ -12,9 +33,13 @@ document.addEventListener('ft:pageChange', () => { __socket = undefined; console.log("Page changed"); }) + function getSocket(): Socket { + // let addressHost = `wss://${machineHostName}:8888`; + let addressHost = `wss://localhost:8888`; if (__socket === undefined) - __socket = io("wss://localhost:8888", { + + __socket = io(addressHost, { path: "/api/chat/socket.io/", secure: false, transports: ["websocket"], @@ -23,12 +48,90 @@ function getSocket(): Socket { } +async function isLoggedIn() { + return getUser() || null; +} + +async function windowStateHidden() { + const socketId = __socket || undefined; + // let oldName = localStorage.getItem("oldName") ?? undefined; + let oldName: string; + if (socketId === undefined) return; + let userName = await updateUser(); + oldName = userName?.name ?? ""; + if (oldName === "") return; + localStorage.setItem('oldName', oldName); + socketId.emit('client_left', { + user: userName?.name, + why: 'tab window hidden - socket not dead', + }); + return; +} + + +async function windowStateVisable() { + const socketId = __socket || undefined; + let oldName = localStorage.getItem("oldName") || undefined; + console.log("%c WINDOW VISIBLE - oldName :'" + oldName + "'", color.green); + + if (socketId === undefined || oldName === undefined) {console.log("%SOCKET ID", color.red); return;} + // const res = await client.guestLogin(); + let user = await updateUser(); + if(user === null) return; + console.log("%cUserName :'" + user?.name + "'", color.green); + socketId.emit('client_entered', { + userName: oldName, + user: user?.name, + }); + setTitle('Chat Page'); + return; +} + + +async function listBuddies(buddies: HTMLDivElement, listBuddies: string ) { + + if (!buddies) return; + const messageElement = document.createElement("div-buddies-list"); + messageElement.textContent = listBuddies + '\n'; + buddies.appendChild(messageElement); + buddies.scrollTop = buddies.scrollHeight; + console.log(`Added buddies: ${listBuddies}`) + return ; + +} + +function waitSocketConnected(socket: Socket): Promise { + return new Promise(resolve => { + if (socket.connected) return resolve(); // already connected + socket.on("connect", () => resolve()); + }); +} +const bconnected = document.getElementById('b-help') as HTMLButtonElement; +if (bconnected) { + bconnected.click(); +} + +function logout(socket: Socket) { + socket.emit("logout"); // notify server + socket.disconnect(); // actually close the socket + localStorage.clear(); + if (__socket !== undefined) + __socket.close(); +// window.location.href = "/login"; +} function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn { + + let socket = getSocket(); + + + // Listen for the 'connect' event - socket.on("connect", () => { + socket.on("connect", async () => { + + await waitSocketConnected(socket); console.log("I AM Connected to the server:", socket.id); const user = getUser()?.name; // Ensure we have a user AND socket is connected @@ -43,31 +146,54 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn }; socket.emit('message', JSON.stringify(message)); }); + // Listen for messages from the server "MsgObjectServer" - socket.on("MsgObjectServer", (data: any) => { - console.log("Message Obj Recieved:", data.message); - console.log("Recieved data.message.text: ", data.message.text); - console.log("Recieved data.message.user: ", data.message.user); - console.log("Recieved data.message.type: ", data.message.type); - console.log("Recieved data.message.token: ", data.message.token); - console.log("Recieved data.message.timestamp: ", data.message.timestamp); + socket.on("MsgObjectServer", (data: { message: ClientMessage}) => { + console.log("Message Obj Recieved:", data); + console.log("%cRecieved data.message.text: ", color.blue, data.message.text); + console.log("%cRecieved data.message.user: ", color.blue, data.message.user); // Display the message in the chat window + const systemWindow = document.getElementById('system-box') as HTMLDivElement; const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement; - if (chatWindow) { + const bconnected = document.getElementById('b-help') as HTMLButtonElement; + if (bconnected) { + bconnected.click(); + } + + if (chatWindow && data.message.destination === "") { const messageElement = document.createElement("div"); - // if (getUser()?.id !== `${data.message.id}`) { - console.log('==================> HERE'); messageElement.textContent = `${data.message.user}: ${data.message.text}`; - // } else { - // console.log('==================>AND HERE'); - // messageElement.textContent = `here`; - // } chatWindow.appendChild(messageElement); chatWindow.scrollTop = chatWindow.scrollHeight; } + const MAX_SYSTEM_MESSAGES = 10; + + if (systemWindow && data.message.destination === "system-info") { + const messageElement = document.createElement("div"); + messageElement.textContent = `${data.message.user}: ${data.message.text}`; + systemWindow.appendChild(messageElement); + + // keep only last 10 + while (systemWindow.children.length > MAX_SYSTEM_MESSAGES) { + systemWindow.removeChild(systemWindow.firstChild!); + } + + systemWindow.scrollTop = systemWindow.scrollHeight; + } + console.log("Getuser():", getUser()); }); + + + + socket.on('logout', () => { + const bquit = document.getElementById('b-quit') as HTMLDivElement | null; + if (bquit instanceof HTMLDivElement) { + bquit.click(); + } + }); + type Providers = { name: string, display_name: string, @@ -75,7 +201,25 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn color?: { default: string, hover: string }, }; - // function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn { + + let toggle = false + window.addEventListener("focus", () => { + const bwhoami = document.getElementById('b-whoami') as HTMLButtonElement; + if (window.location.pathname === '/app/chat') { + console.log("%cWindow is focused on /chat:" + socket.id, color.green); + if (socket.id) + windowStateVisable(); + bwhoami.click(); + toggle = true; + } + }); + + window.addEventListener("blur", () => { + console.log("%cWindow is not focused on /chat", color.red); + if (socket.id) + windowStateHidden(); + toggle = false; + }); setTitle('Chat Page'); // Listen for the 'connect' event @@ -89,34 +233,53 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn const bwhoami = document.getElementById('b-whoami') as HTMLButtonElement; const bconnected = document.getElementById('b-help') as HTMLButtonElement; const username = document.getElementById('username') as HTMLDivElement; + const buddies = document.getElementById('div-buddies') as HTMLDivElement; + const bquit = document.getElementById('b-quit') as HTMLDivElement; + + chatWindow.textContent = ''; + chatWindow.innerHTML = ''; + buddies.textContent = ''; + buddies.innerHTML = ''; + const value = await client.chatTest(); - if (value.kind === "success") { - console.log(value.payload); - } else if (value.kind === "notLoggedIn") { - console.log('not logged in'); - } else { - console.log('unknown response: ', value); - } - + if (value.kind === "success") { + console.log(value.payload); + } else if (value.kind === "notLoggedIn") { + console.log('not logged in'); + } else { + console.log('unknown response: ', value); + } const addMessage = (text: string) => { if (!chatWindow) return; - const messageElement = document.createElement("div"); + const messageElement = document.createElement("div-test"); messageElement.textContent = text; chatWindow.appendChild(messageElement); chatWindow.scrollTop = chatWindow.scrollHeight; console.log(`Added new message: ${text}`) + return ; }; + socket.once('welcome', (data) => { + chatWindow.textContent = ''; + chatWindow.innerHTML = ''; + buddies.textContent = ''; + buddies.innerHTML = ''; + bconnected.click(); + addMessage (`${data.msg} ` + getUser()?.name); + }); + // Send button sendButton?.addEventListener("click", () => { if (sendtextbox && sendtextbox.value.trim()) { const msgText = sendtextbox.value.trim(); + bconnected.click(); addMessage(msgText); const user = getUser(); if (user && socket?.connected) { const message = { + destination: "", type: "chat", user: user.name, token: document.cookie, @@ -124,31 +287,66 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn timestamp: Date.now(), SenderWindowID: socket.id, }; - socket.send(JSON.stringify(message)); + socket.emit('message', JSON.stringify(message)); } sendtextbox.value = ""; } }); + + // Clear Text button clearText?.addEventListener("click", () => { + if (chatWindow) { + bconnected.click(); chatWindow.innerHTML = ''; } }); + bquit?.addEventListener('click', () => { + if (socket) { + logout(socket); + setTitle('Chat Page'); + bconnected.click(); + } else { + getSocket(); + } + }); + + + setInterval(async () => { + //bconnected.click(); + }, 10000); // every 10 second // Help Text button bconnected?.addEventListener("click", async () => { - if (chatWindow) { - addMessage('@list - lists all connected users in the chat'); - await socket.emit('list'); - } + + const loggedIn = await isLoggedIn(); + console.log('%cloggedIn:',color.blue, loggedIn?.name); + let oldUser = localStorage.getItem("oldName") ?? ""; + console.log('%coldUser:',color.yellow, oldUser); + if (loggedIn?.name === undefined) {console.log('');return ;} + oldUser = loggedIn.name || "undefined"; + const res = await client.guestLogin(); + let user = await updateUser(); + console.log('%cUser?name:',color.yellow, user?.name); + localStorage.setItem("oldName", oldUser); + buddies.textContent = ""; + // if (chatWindow) { + // addMessage('@list - lists all connected users in the chat'); + socket.emit('list', { + oldUser: oldUser, + user: user?.name, + }); + // } + }); - socket.on('listObj', (list: string) => { - console.log('List chat clients connected ', list); - addMessage(list); + + socket.on('listBud', (myBuddies: string) => { + console.log('List buddies connected ', myBuddies); + listBuddies(buddies,myBuddies); }); @@ -162,10 +360,18 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn // Whoami button to display user name bwhoami?.addEventListener('click', async () => { try { + const loggedIn = await isLoggedIn(); + const res = await client.guestLogin(); switch (res.kind) { case 'success': { let user = await updateUser(); + if (chatWindow) { + socket.emit('updateClientName', { + oldUser: '', + user: user?.name + }); + } if (user === null) return showError('Failed to get user: no user ?'); setTitle(`Welcome ${user.guest ? '[GUEST] ' : ''}${user.name}`); @@ -184,3 +390,4 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn } }; addRoute('/chat', handleChat, { bypass_auth: true }); + diff --git a/src/@shared/package.json b/src/@shared/package.json index edcf6a8..d563f63 100644 --- a/src/@shared/package.json +++ b/src/@shared/package.json @@ -20,8 +20,8 @@ "fastify-plugin": "^5.1.0", "joi": "^18.0.2", "otp": "^1.1.2", - "typebox": "^1.0.55", - "uuidv7": "^1.0.2" + "typebox": "^1.0.61", + "uuidv7": "^1.1.0" }, "devDependencies": { "@types/better-sqlite3": "^7.6.13", diff --git a/src/@shared/src/database/index.ts b/src/@shared/src/database/index.ts index 597efac..ea111db 100644 --- a/src/@shared/src/database/index.ts +++ b/src/@shared/src/database/index.ts @@ -4,11 +4,13 @@ import { FastifyInstance, FastifyPluginAsync } from 'fastify'; import { isNullish } from '@shared/utils'; import { Database as DbImpl } from './mixin/_base'; import { IUserDb, UserImpl } from './mixin/user'; +import { IBlockedDb, BlockedImpl } from './mixin/blocked'; Object.assign(DbImpl.prototype, UserImpl); +Object.assign(DbImpl.prototype, BlockedImpl); -export interface Database extends DbImpl, IUserDb { } +export interface Database extends DbImpl, IUserDb, IBlockedDb { } // When using .decorate you have to specify added properties for Typescript declare module 'fastify' { diff --git a/src/@shared/src/database/init.sql b/src/@shared/src/database/init.sql index b53675b..b77edfe 100644 --- a/src/@shared/src/database/init.sql +++ b/src/@shared/src/database/init.sql @@ -7,3 +7,17 @@ CREATE TABLE IF NOT EXISTS user ( guest INTEGER NOT NULL DEFAULT 0, oauth2 TEXT DEFAULT NULL ); + + +CREATE TABLE IF NOT EXISTS blocked ( + id INTEGER PRIMARY KEY NOT NULL, + user TEXT NOT NULL, + blocked TEXT NOT NULL, + + FOREIGN KEY(user) REFERENCES user(id) + FOREIGN KEY(blocked) REFERENCES user(id) +); + +CREATE UNIQUE INDEX IF NOT EXISTS idx_blocked_user_pair + ON blocked(user, blocked); + diff --git a/src/@shared/src/database/mixin/blocked.ts b/src/@shared/src/database/mixin/blocked.ts new file mode 100644 index 0000000..a6b0a28 --- /dev/null +++ b/src/@shared/src/database/mixin/blocked.ts @@ -0,0 +1,72 @@ +import { isNullish } from '@shared/utils'; +import type { Database } from './_base'; +import { UserId } from './user'; + + +// describe every function in the object +export interface IBlockedDb extends Database { + getBlockedUserFor(id: UserId): BlockedData[], + addBlockedUserFor(id: UserId, blocked: UserId): void, + removeBlockedUserFor(id: UserId, blocked: UserId): void, + unblockAllUserFor(id: UserId): void, + getAllBlockedUsers(this: IBlockedDb): BlockedData[] | undefined, + +}; + +export const BlockedImpl: Omit = { + getBlockedUserFor(this: IBlockedDb, id: UserId): BlockedData[] { + const query = this.prepare('SELECT * FROM blocked WHERE user = @id'); + const data = query.all({ id }) as Partial[]; + return data.map(blockedFromRow).filter(b => !isNullish(b)); + }, + + unblockAllUserFor(this: IBlockedDb, id: UserId): void { + this.prepare('DELETE FROM blocked WHERE user = @id').run({ id }); + }, + addBlockedUserFor(this: IBlockedDb, id: UserId, blocked: UserId): void { + this.prepare('INSERT OR IGNORE INTO blocked (user, blocked) VALUES (@id, @blocked)').run({ id, blocked }); + }, + removeBlockedUserFor(this: IBlockedDb, id: UserId, blocked: UserId): void { + this.prepare('DELETE FROM blocked WHERE user = @id AND blocked = @blocked').run({ id, blocked }); + }, + + /** + * Get all blocked user + * + * @param + * + * @returns The list of users if it exists, undefined otherwise + */ + getAllBlockedUsers(this: IBlockedDb): BlockedData[] { + const rows = this.prepare('SELECT * FROM blocked').all() as Partial[]; + + return rows + .map(row => blockedFromRow(row)) + .filter((u): u is BlockedData => u !== undefined); + }, + +}; + +export type BlockedId = number & { readonly __brand: unique symbol }; + +export type BlockedData = { + readonly id: BlockedId; + readonly user: UserId; + readonly blocked: UserId; +}; + +/** + * Get a blocked from a row + * + * @param row The data from sqlite + * + * @returns The blocked if it exists, undefined otherwise + */ +export function blockedFromRow(row?: Partial): BlockedData | undefined { + if (isNullish(row)) return undefined; + if (isNullish(row.id)) return undefined; + if (isNullish(row.user)) return undefined; + if (isNullish(row.blocked)) return undefined; + + return row as BlockedData; +} diff --git a/src/@shared/src/database/mixin/user.ts b/src/@shared/src/database/mixin/user.ts index 558bfee..a931aa8 100644 --- a/src/@shared/src/database/mixin/user.ts +++ b/src/@shared/src/database/mixin/user.ts @@ -18,6 +18,8 @@ export interface IUserDb extends Database { ensureUserOtpSecret(id: UserId): string | undefined, deleteUserOtpSecret(id: UserId): void, getAllUserFromProvider(provider: string): User[] | undefined, + getAllUsers(this: IUserDb): User[] | undefined, + }; export const UserImpl: Omit = { @@ -36,6 +38,15 @@ export const UserImpl: Omit = { ); }, + getAllUsers(this: IUserDb): User[] { + const rows = this.prepare('SELECT * FROM user').all() as Partial[]; + + return rows + .map(row => userFromRow(row)) + .filter((u): u is User => u !== undefined); + }, + + /** * Get a user from a raw [UserId] * diff --git a/src/auth/package.json b/src/auth/package.json index 855e7f8..81d3afe 100644 --- a/src/auth/package.json +++ b/src/auth/package.json @@ -21,18 +21,18 @@ "@fastify/autoload": "^6.3.1", "@fastify/formbody": "^8.0.2", "@fastify/multipart": "^9.3.0", - "@fastify/sensible": "^6.0.3", + "@fastify/sensible": "^6.0.4", "@fastify/static": "^8.3.0", "confbox": "^0.2.2", "fastify": "^5.6.2", "fastify-cli": "^7.4.1", "fastify-plugin": "^5.1.0", - "typebox": "^1.0.55" + "typebox": "^1.0.61" }, "devDependencies": { "@types/node": "^22.19.1", "rollup-plugin-node-externals": "^8.1.2", - "vite": "^7.2.4", + "vite": "^7.2.6", "vite-tsconfig-paths": "^5.1.4" } } diff --git a/src/chat/openapi.json b/src/chat/openapi.json index 8afe3d2..bcebf94 100644 --- a/src/chat/openapi.json +++ b/src/chat/openapi.json @@ -112,32 +112,6 @@ } } } - }, - "500": { - "description": "Default Response", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "kind", - "msg" - ], - "properties": { - "kind": { - "enum": [ - "failed" - ] - }, - "msg": { - "enum": [ - "chat.failed.generic" - ] - } - } - } - } - } } } } diff --git a/src/chat/package.json b/src/chat/package.json index 7a504d7..1e61398 100644 --- a/src/chat/package.json +++ b/src/chat/package.json @@ -21,18 +21,18 @@ "@fastify/autoload": "^6.3.1", "@fastify/formbody": "^8.0.2", "@fastify/multipart": "^9.3.0", - "@fastify/sensible": "^6.0.3", + "@fastify/sensible": "^6.0.4", "@fastify/static": "^8.3.0", "@fastify/websocket": "^11.2.0", - "@sinclair/typebox": "^0.34.41", "fastify": "^5.6.2", "fastify-plugin": "^5.1.0", - "socket.io": "^4.8.1" + "socket.io": "^4.8.1", + "typebox": "^1.0.61" }, "devDependencies": { "@types/node": "^22.19.1", "rollup-plugin-node-externals": "^8.1.2", - "vite": "^7.2.4", + "vite": "^7.2.6", "vite-tsconfig-paths": "^5.1.4" } } diff --git a/src/chat/src/app.ts b/src/chat/src/app.ts index 4749bb9..4ac2c96 100644 --- a/src/chat/src/app.ts +++ b/src/chat/src/app.ts @@ -7,11 +7,40 @@ import * as swagger from '@shared/swagger'; import * as utils from '@shared/utils'; import { Server, Socket } from 'socket.io'; +// colors for console.log +export const color = { + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + reset: '\x1b[0m', +}; + +// shows address for connection au server transcendance +const session = process.env.SESSION_MANAGER ?? ''; +if (session) { + const part = session.split('/')[1]; + const machineName = part.split('.')[0]; + console.log(color.yellow, 'Connect at : https://' + machineName + ':8888/app/login'); +} + declare const __SERVICE_NAME: string; // Global map of clients // key = socket, value = clientname -const clientChat = new Map(); +interface ClientInfo { + user: string; + lastSeen: number; +} + +export type ClientMessage = { + destination: string; + user: string; + text: string; + SenderWindowID: string; +}; + +const clientChat = new Map(); // @ts-expect-error: import.meta.glob is a vite thing. Typescript doesn't know this... const plugins = import.meta.glob('./plugins/**/*.ts', { eager: true }); @@ -47,20 +76,6 @@ const app: FastifyPluginAsync = async (fastify, opts): Promise => { export default app; export { app }; -export const color = { - red: '\x1b[31m', - green: '\x1b[32m', - yellow: '\x1b[33m', - blue: '\x1b[34m', - reset: '\x1b[0m', -}; - -type ClientMessage = { - user: string; - text: string; - SenderWindowID: string; -}; - // When using .decorate you have to specify added properties for Typescript declare module 'fastify' { interface FastifyInstance { @@ -68,7 +83,12 @@ declare module 'fastify' { hello: (message: string) => string; MsgObjectServer: (data: { message: ClientMessage }) => void; message: (msg: string) => void; + listBud: (msg: string) => void; testend: (sock_id_client: string) => void; + client_entered: (userName: string, user: string) => void; + client_left: (userName: string, why: string) => void; + list: (oldUser: string, user: string) => void; + updateClientName: (oldUser: string, user: string) => void; }>; } } @@ -85,7 +105,7 @@ async function onReady(fastify: FastifyInstance) { clientChat.delete(socketId); continue; } - if (typeof username !== 'string' || username.length === 0) { + if (typeof username.user !== 'string' || username.user.length === 0) { clientChat.delete(socketId); continue; } @@ -102,18 +122,17 @@ async function onReady(fastify: FastifyInstance) { } // Skip duplicates (DO NOT delete them — just don't count) - if (seen.has(username)) { + if (seen.has(username.user)) { continue; } // socket exists and is connected - seen.add(username); + seen.add(username.user); count++; // console.log(color.green,"count: ", count); - console.log(color.yellow, 'Client:', color.reset, username); + console.log(color.yellow, 'Client:', color.reset, username.user); const targetSocketId = target; - io.to(targetSocketId!).emit('listObj', username); - + io.to(targetSocketId!).emit('listBud', username.user); console.log( color.yellow, 'Chat Socket ID:', @@ -138,28 +157,33 @@ async function onReady(fastify: FastifyInstance) { socketId, ); } - return count; } function broadcast(data: ClientMessage, sender?: string) { fastify.io.fetchSockets().then((sockets) => { for (const s of sockets) { - if (s.id !== sender) { - // Send REAL JSON object - const clientName = clientChat.get(s.id) || null; - if (clientName !== null) { - s.emit('MsgObjectServer', { message: data }); - } - console.log(' Target window socket ID:', s.id); - console.log(' Target window ID:', [...s.rooms]); - console.log(' Sender window ID:', sender ? sender : 'none'); + // Skip sender's own socket + if (s.id === sender) continue; + // Get client name from map + const clientInfo = clientChat.get(s.id); + if (!clientInfo?.user) { + console.log(color.yellow, `Skipping socket ${s.id} (no user found)`); + continue; } + // Emit structured JSON object + s.emit('MsgObjectServer', { message: data }); + // Debug logs + console.log(color.green, 'Broadcast to:', clientInfo.user); + console.log(' Target socket ID:', s.id); + console.log(' Target rooms:', [...s.rooms]); + console.log(' Sender socket ID:', sender ?? 'none'); } }); } fastify.io.on('connection', (socket: Socket) => { + socket.on('message', (message: string) => { console.info( color.blue, @@ -175,13 +199,17 @@ async function onReady(fastify: FastifyInstance) { ); const obj: ClientMessage = JSON.parse(message) as ClientMessage; - clientChat.set(socket.id, obj.user); + clientChat.set(socket.id, { user: obj.user, lastSeen: Date.now() }); console.log( color.green, 'Message from client', color.reset, - `Sender: login name: "${obj.user}" - windowID "${obj.SenderWindowID}" - text message: "${obj.text}"`, + `Sender: login name: ${obj.user} - windowID ${obj.SenderWindowID} - text message: ${obj.text}`, ); + socket.emit('welcome', { + msg: 'Welcome to the chat! : ', + }); + // Send object directly — DO NOT wrap it in a string broadcast(obj, obj.SenderWindowID); console.log( @@ -196,13 +224,68 @@ async function onReady(fastify: FastifyInstance) { console.log('testend received from client socket id:', sock_id_cl); }); - socket.on('list', () => { - console.log(color.red, 'list activated', color.reset, socket.id); + socket.on('list', (object) => { + + const userFromFrontend = object || null; + const client = clientChat.get(socket.id) || null; + + console.log(color.red, 'list activated', userFromFrontend, color.reset, socket.id); + + if (userFromFrontend.oldUser !== userFromFrontend.user) { + console.log(color.red, 'list activated', userFromFrontend.oldUser, color.reset); + // if (client?.user === null) { + // console.log('ERROR: clientName is NULL'); + // return; + // }; + if (client) { + client.user = userFromFrontend.user; + } + } connectedUser(fastify.io, socket.id); }); + socket.on('updateClientName', (object) => { + const userFromFrontend = object || null; + const client = clientChat.get(socket.id) || null; + console.log(color.red, 'whoAMi activated', userFromFrontend, color.reset, socket.id); + if (userFromFrontend.oldUser !== userFromFrontend.user) { + console.log(color.red, 'whoAMi activated', userFromFrontend.oldUser, color.reset); + // if (client === null) { + // console.log('ERROR: clientName is NULL'); + // return; + // }; + if (client) { + client.user = userFromFrontend.user; + console.log(color.green, 'client.user is: ', client.user); + + } + } + }); + + socket.on('logout', () => { + const clientInfo = clientChat.get(socket.id); + const clientName = clientInfo?.user; + + if (!clientName) return; + console.log(color.green, `Client logging out: ${clientName} (${socket.id})`); + const obj = { + destination: 'system-info', + type: 'chat' as const, + user: clientName, + token: '', + text: 'LEFT the chat', + timestamp: Date.now(), + SenderWindowID: socket.id, + }; + broadcast(obj, socket.id); + // Optional: remove from map + clientChat.delete(socket.id); + // Ensure socket is fully disconnected + if (socket.connected) socket.disconnect(true); + }); + socket.on('disconnecting', (reason) => { - const clientName = clientChat.get(socket.id) || null; + const clientName = clientChat.get(socket.id)?.user || null; console.log( color.green, `Client disconnecting: ${clientName} (${socket.id}) reason:`, @@ -212,6 +295,7 @@ async function onReady(fastify: FastifyInstance) { if (clientName !== null) { const obj = { + destination: 'system-info', type: 'chat', user: clientName, token: '', @@ -221,8 +305,78 @@ async function onReady(fastify: FastifyInstance) { }; broadcast(obj, obj.SenderWindowID); + } + }); + + socket.on('client_left', (data) => { + const clientName = clientChat.get(socket.id)?.user || null; + const leftChat = data || null; + console.log( + color.green, + `Left the Chat User: ${clientName} id Socket: ${socket.id} reason:`, + leftChat.why, + ); + + if (clientName !== null) { + const obj = { + destination: 'system-info', + type: 'chat', + user: clientName, + token: '', + text: 'LEFT the chat but the window is still open', + timestamp: Date.now(), + SenderWindowID: socket.id, + }; + console.log(color.blue, 'BROADCASTS OUT :', obj.SenderWindowID); + broadcast(obj, obj.SenderWindowID); // clientChat.delete(obj.user); } }); + + socket.on('client_entered', (data) => { + + // data may be undefined (when frontend calls emit with no payload) + const userNameFromFrontend = data?.userName || null; + const userFromFrontend = data?.user || null; + let clientName = clientChat.get(socket.id)?.user || null; + // const client = clientChat.get(socket.id) || null; + let text = 'is back in the chat'; + + if (clientName === null) { + console.log('ERROR: clientName is NULL'); return; + }; + // if (client === null) { + // console.log('ERROR: client is NULL'); return; + // }; + if (userNameFromFrontend !== userFromFrontend) { + text = `'is back in the chat, I used to be called '${userNameFromFrontend}`; + clientName = userFromFrontend; + if (clientName === null) { + console.log('ERROR: clientName is NULL'); return; + }; + // if (client) { + // client.user = clientName; + // } + } + console.log( + color.green, + `Client entered the Chat: ${clientName} (${socket.id})`, + ); + if (clientName !== null) { + const obj = { + destination: 'system-info', + type: 'chat', + user: clientName, + frontendUserName: userNameFromFrontend, + frontendUser: userFromFrontend, + token: '', + text: text, + timestamp: Date.now(), + SenderWindowID: socket.id, + }; + broadcast(obj, obj.SenderWindowID); + } + }); + }); } diff --git a/src/chat/src/routes/nginx-chat.ts b/src/chat/src/routes/nginx-chat.ts index d3aaebb..02162cc 100644 --- a/src/chat/src/routes/nginx-chat.ts +++ b/src/chat/src/routes/nginx-chat.ts @@ -1,6 +1,17 @@ import { FastifyPluginAsync } from 'fastify'; import { MakeStaticResponse, typeResponse } from '@shared/utils'; -import { Type } from '@sinclair/typebox'; +import { Type } from 'typebox'; +// import { UserId } from '@shared/database/mixin/user'; +// import { Server } from 'socket.io'; + +// colors for console.log +export const color = { + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + reset: '\x1b[0m', +}; export const ChatRes = { 200: typeResponse('success', 'chat.success', { @@ -23,8 +34,19 @@ const route: FastifyPluginAsync = async (fastify): Promise => { config: { requireAuth: true }, }, async (req, res) => { - // console.log('/api/chat/test called =================>'); - res.makeResponse(200, 'success', 'CCChat.success', { name: 'My_namw', 'id': req.authUser!.id, guest: false }); + + // const users = fastify.db.getAllUsers(); + // console.log('ALL USERS EVER CONNECTED:', users); + // if (!users) return; + // for (const user of users) { + // console.log(color.yellow, 'USER:', user.name); + // } + // // const usersBlocked = fastify.db.getAllBlockedUsers(); + // // console.log(color.red, "ALL BLOCKED USERS:", usersBlocked); + // fastify.db.addBlockedUserFor(users[0].id, users[1].id); + // const usersBlocked2 = fastify.db.getAllBlockedUsers(); + // console.log(color.green, 'ALL BLOCKED USERS:', usersBlocked2); + res.makeResponse(200, 'success', 'CCChat.success', { name: 'name', 'id': req.authUser!.id, guest: false }); }, ); }; diff --git a/src/icons/package.json b/src/icons/package.json index 1952efc..3bef3d5 100644 --- a/src/icons/package.json +++ b/src/icons/package.json @@ -20,7 +20,7 @@ "@fastify/autoload": "^6.3.1", "@fastify/formbody": "^8.0.2", "@fastify/multipart": "^9.3.0", - "@fastify/sensible": "^6.0.3", + "@fastify/sensible": "^6.0.4", "@fastify/static": "^8.3.0", "fastify": "^5.6.2", "fastify-cli": "^7.4.1", @@ -31,7 +31,7 @@ "devDependencies": { "@types/node": "^22.19.1", "rollup-plugin-node-externals": "^8.1.2", - "vite": "^7.2.4", + "vite": "^7.2.6", "vite-tsconfig-paths": "^5.1.4" } } diff --git a/src/openapi.json b/src/openapi.json index f370df1..4327973 100644 --- a/src/openapi.json +++ b/src/openapi.json @@ -1294,32 +1294,6 @@ } } } - }, - "500": { - "description": "Default Response", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "kind", - "msg" - ], - "properties": { - "kind": { - "enum": [ - "failed" - ] - }, - "msg": { - "enum": [ - "chat.failed.generic" - ] - } - } - } - } - } } }, "tags": [ diff --git a/src/package.json b/src/package.json index 22edb07..9fa1e9c 100644 --- a/src/package.json +++ b/src/package.json @@ -24,19 +24,19 @@ "devDependencies": { "@eslint/js": "^9.39.1", "@openapitools/openapi-generator-cli": "^2.25.2", - "@typescript-eslint/eslint-plugin": "^8.48.0", - "@typescript-eslint/parser": "^8.48.0", + "@typescript-eslint/eslint-plugin": "^8.48.1", + "@typescript-eslint/parser": "^8.48.1", "eslint": "^9.39.1", "husky": "^9.1.7", "lint-staged": "^16.2.7", "openapi-generator-cli": "^1.0.0", "openapi-typescript": "^7.10.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.48.0", - "vite": "^7.2.4" + "typescript-eslint": "^8.48.1", + "vite": "^7.2.6" }, "dependencies": { - "@redocly/cli": "^2.11.1", + "@redocly/cli": "^2.12.1", "bindings": "^1.5.0" } } diff --git a/src/pnpm-lock.yaml b/src/pnpm-lock.yaml index e77156a..ad74292 100644 --- a/src/pnpm-lock.yaml +++ b/src/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@redocly/cli': - specifier: ^2.11.1 - version: 2.11.1(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0) + specifier: ^2.12.1 + version: 2.12.1(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0) bindings: specifier: ^1.5.0 version: 1.5.0 @@ -22,11 +22,11 @@ importers: specifier: ^2.25.2 version: 2.25.2(@types/node@24.10.1) '@typescript-eslint/eslint-plugin': - specifier: ^8.48.0 - version: 8.48.0(@typescript-eslint/parser@8.48.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) + specifier: ^8.48.1 + version: 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: ^8.48.0 - version: 8.48.0(eslint@9.39.1)(typescript@5.9.3) + specifier: ^8.48.1 + version: 8.48.1(eslint@9.39.1)(typescript@5.9.3) eslint: specifier: ^9.39.1 version: 9.39.1 @@ -46,11 +46,11 @@ importers: specifier: ^5.9.3 version: 5.9.3 typescript-eslint: - specifier: ^8.48.0 - version: 8.48.0(eslint@9.39.1)(typescript@5.9.3) + specifier: ^8.48.1 + version: 8.48.1(eslint@9.39.1)(typescript@5.9.3) vite: - specifier: ^7.2.4 - version: 7.2.4(@types/node@24.10.1)(yaml@2.8.1) + specifier: ^7.2.6 + version: 7.2.6(@types/node@24.10.1)(yaml@2.8.2) '@shared': dependencies: @@ -88,11 +88,11 @@ importers: specifier: ^1.1.2 version: 1.1.2 typebox: - specifier: ^1.0.55 - version: 1.0.55 + specifier: ^1.0.61 + version: 1.0.61 uuidv7: - specifier: ^1.0.2 - version: 1.0.2 + specifier: ^1.1.0 + version: 1.1.0 devDependencies: '@types/better-sqlite3': specifier: ^7.6.13 @@ -113,8 +113,8 @@ importers: specifier: ^9.3.0 version: 9.3.0 '@fastify/sensible': - specifier: ^6.0.3 - version: 6.0.3 + specifier: ^6.0.4 + version: 6.0.4 '@fastify/static': specifier: ^8.3.0 version: 8.3.0 @@ -131,8 +131,8 @@ importers: specifier: ^5.1.0 version: 5.1.0 typebox: - specifier: ^1.0.55 - version: 1.0.55 + specifier: ^1.0.61 + version: 1.0.61 devDependencies: '@types/node': specifier: ^22.19.1 @@ -141,11 +141,11 @@ importers: specifier: ^8.1.2 version: 8.1.2(rollup@4.53.3) vite: - specifier: ^7.2.4 - version: 7.2.4(@types/node@22.19.1)(yaml@2.8.1) + specifier: ^7.2.6 + version: 7.2.6(@types/node@22.19.1)(yaml@2.8.2) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.1)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.6(@types/node@22.19.1)(yaml@2.8.2)) chat: dependencies: @@ -159,17 +159,14 @@ importers: specifier: ^9.3.0 version: 9.3.0 '@fastify/sensible': - specifier: ^6.0.3 - version: 6.0.3 + specifier: ^6.0.4 + version: 6.0.4 '@fastify/static': specifier: ^8.3.0 version: 8.3.0 '@fastify/websocket': specifier: ^11.2.0 version: 11.2.0 - '@sinclair/typebox': - specifier: ^0.34.41 - version: 0.34.41 fastify: specifier: ^5.6.2 version: 5.6.2 @@ -179,6 +176,9 @@ importers: socket.io: specifier: ^4.8.1 version: 4.8.1 + typebox: + specifier: ^1.0.61 + version: 1.0.61 devDependencies: '@types/node': specifier: ^22.19.1 @@ -187,11 +187,11 @@ importers: specifier: ^8.1.2 version: 8.1.2(rollup@4.53.3) vite: - specifier: ^7.2.4 - version: 7.2.4(@types/node@22.19.1)(yaml@2.8.1) + specifier: ^7.2.6 + version: 7.2.6(@types/node@22.19.1)(yaml@2.8.2) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.1)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.6(@types/node@22.19.1)(yaml@2.8.2)) icons: dependencies: @@ -205,8 +205,8 @@ importers: specifier: ^9.3.0 version: 9.3.0 '@fastify/sensible': - specifier: ^6.0.3 - version: 6.0.3 + specifier: ^6.0.4 + version: 6.0.4 '@fastify/static': specifier: ^8.3.0 version: 8.3.0 @@ -233,11 +233,11 @@ importers: specifier: ^8.1.2 version: 8.1.2(rollup@4.53.3) vite: - specifier: ^7.2.4 - version: 7.2.4(@types/node@22.19.1)(yaml@2.8.1) + specifier: ^7.2.6 + version: 7.2.6(@types/node@22.19.1)(yaml@2.8.2) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.1)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.6(@types/node@22.19.1)(yaml@2.8.2)) user: dependencies: @@ -251,8 +251,8 @@ importers: specifier: ^9.3.0 version: 9.3.0 '@fastify/sensible': - specifier: ^6.0.3 - version: 6.0.3 + specifier: ^6.0.4 + version: 6.0.4 '@fastify/static': specifier: ^8.3.0 version: 8.3.0 @@ -266,8 +266,8 @@ importers: specifier: ^5.1.0 version: 5.1.0 typebox: - specifier: ^1.0.55 - version: 1.0.55 + specifier: ^1.0.61 + version: 1.0.61 devDependencies: '@types/node': specifier: ^22.19.1 @@ -276,11 +276,11 @@ importers: specifier: ^8.1.2 version: 8.1.2(rollup@4.53.3) vite: - specifier: ^7.2.4 - version: 7.2.4(@types/node@22.19.1)(yaml@2.8.1) + specifier: ^7.2.6 + version: 7.2.6(@types/node@22.19.1)(yaml@2.8.2) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.1)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.6(@types/node@22.19.1)(yaml@2.8.2)) packages: @@ -489,8 +489,8 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/js@9.39.1': @@ -557,8 +557,8 @@ packages: '@fastify/send@4.1.0': resolution: {integrity: sha512-TMYeQLCBSy2TOFmV95hQWkiTYgC/SEx7vMdV+wnZVX4tt8VBLKzmH8vV9OzJehV0+XBfg+WxPMt5wp+JBUKsVw==} - '@fastify/sensible@6.0.3': - resolution: {integrity: sha512-Iyn8698hp/e5+v8SNBBruTa7UfrMEP52R16dc9jMpqSyEcPsvWFQo+R6WwHCUnJiLIsuci2ZoEZ7ilrSSCPIVg==} + '@fastify/sensible@6.0.4': + resolution: {integrity: sha512-1vxcCUlPMew6WroK8fq+LVOwbsLtX+lmuRuqpcp6eYqu6vmkLwbKTdBWAZwbeaSgCfW4tzUpTIHLLvTiQQ1BwQ==} '@fastify/static@8.3.0': resolution: {integrity: sha512-yKxviR5PH1OKNnisIzZKmgZSus0r2OZb8qCSbqmw34aolT4g3UlzYfeBRym+HJ1J471CR8e2ldNub4PubD1coA==} @@ -940,33 +940,30 @@ packages: '@protobufjs/utf8@1.1.0': resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - '@redocly/ajv@8.11.4': - resolution: {integrity: sha512-77MhyFgZ1zGMwtCpqsk532SJEc3IJmSOXKTCeWoMTAvPnQOkuOgxEip1n5pG5YX1IzCTJ4kCvPKr8xYyzWFdhg==} - '@redocly/ajv@8.17.1': resolution: {integrity: sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==} - '@redocly/cli@2.11.1': - resolution: {integrity: sha512-doNs+sdrFzzXmyf1yIeJbPh8OChacHWkvTE9N0QbuCmnYQ4k0v1IMP20qsitkwR+fK8O1hXSnFnSTVvIunMVVw==} + '@redocly/cli@2.12.1': + resolution: {integrity: sha512-XGD28QjjZEzN+J9WOROzw4fHNi+Fyw/gCyDZDgI4nX4j9gEBT1PcxN75wWpMoDGHKAUj8ghrhMHtfQoUuR90zg==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} hasBin: true '@redocly/config@0.22.2': resolution: {integrity: sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==} - '@redocly/config@0.38.0': - resolution: {integrity: sha512-kSgMG3rRzgXIP/6gWMRuWbu9/ms0Cyuphcx19dPR9qlgc1tt9IKYPsFQ+KhJuEtqd3bcY/+Uflysf33dQkZWVQ==} + '@redocly/config@0.40.0': + resolution: {integrity: sha512-MZQZs7QEGnue3rVN9Q9QvDbcGjesxbpKXUvDeckS69R1xjtgsnT9B39VA25zmwSJtgUeA9ST+sMf9GxIqixNbw==} '@redocly/openapi-core@1.34.5': resolution: {integrity: sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==} engines: {node: '>=18.17.0', npm: '>=9.5.0'} - '@redocly/openapi-core@2.11.1': - resolution: {integrity: sha512-FVCDnZxaoUJwLQxfW4inCojxUO56J3ntu7dDAE2qyWd6tJBK45CnXMQQUxpqeRTeXROr3jYQoApAw+GCEnyBeg==} + '@redocly/openapi-core@2.12.1': + resolution: {integrity: sha512-xMlKf4dnZsxP3JYBNZFsMNBJqVxWlwLuyGLhGc36hXw50YOla1UjrVZ5psIyzLXgUPI3QJDA1XmGcJ8rcex/ow==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} - '@redocly/respect-core@2.11.1': - resolution: {integrity: sha512-jSMJvCJeo5gmhQfg82AhuwCG0h8gbW5vqHyRITBu8KHVsBiQTgvfhXepu8SKHeJu0OexYtEc0nUnGLJlefevYw==} + '@redocly/respect-core@2.12.1': + resolution: {integrity: sha512-ADm+JMHWGYeOwzdGEQ8CYKjmMBLU0ycZTwJbCkQsUulXSNkNA7GzA8lrMM2+I8cPMRk25G5PmtfAR7U+a0o1ew==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} '@rollup/rollup-android-arm-eabi@4.53.3': @@ -1079,9 +1076,6 @@ packages: cpu: [x64] os: [win32] - '@sinclair/typebox@0.34.41': - resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} - '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} @@ -1125,63 +1119,63 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@typescript-eslint/eslint-plugin@8.48.0': - resolution: {integrity: sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==} + '@typescript-eslint/eslint-plugin@8.48.1': + resolution: {integrity: sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.48.0 + '@typescript-eslint/parser': ^8.48.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.48.0': - resolution: {integrity: sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==} + '@typescript-eslint/parser@8.48.1': + resolution: {integrity: sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.48.0': - resolution: {integrity: sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==} + '@typescript-eslint/project-service@8.48.1': + resolution: {integrity: sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.48.0': - resolution: {integrity: sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==} + '@typescript-eslint/scope-manager@8.48.1': + resolution: {integrity: sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.48.0': - resolution: {integrity: sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==} + '@typescript-eslint/tsconfig-utils@8.48.1': + resolution: {integrity: sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.48.0': - resolution: {integrity: sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==} + '@typescript-eslint/type-utils@8.48.1': + resolution: {integrity: sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.48.0': - resolution: {integrity: sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==} + '@typescript-eslint/types@8.48.1': + resolution: {integrity: sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.48.0': - resolution: {integrity: sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==} + '@typescript-eslint/typescript-estree@8.48.1': + resolution: {integrity: sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.48.0': - resolution: {integrity: sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==} + '@typescript-eslint/utils@8.48.1': + resolution: {integrity: sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.48.0': - resolution: {integrity: sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==} + '@typescript-eslint/visitor-keys@8.48.1': + resolution: {integrity: sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} abort-controller@3.0.0: @@ -1209,14 +1203,6 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: @@ -1479,12 +1465,16 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} core-js@3.47.0: @@ -1726,8 +1716,8 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - fast-copy@3.0.2: - resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} + fast-copy@4.0.0: + resolution: {integrity: sha512-/oA0gx1xyXE9R2YlV4FXwZJXngFdm9Du0zN8FhY38jnLkhp1u35h6bCyKgRhlsA6C9I+1vfXE4KISdt7xc6M9w==} fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -2019,8 +2009,8 @@ packages: resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} - ipaddr.js@2.2.0: - resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} engines: {node: '>= 10'} is-binary-path@2.1.0: @@ -2187,8 +2177,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - lru-cache@11.2.2: - resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} lru-cache@7.18.3: @@ -2213,9 +2203,9 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} @@ -2225,10 +2215,18 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} @@ -2521,8 +2519,11 @@ packages: pino-abstract-transport@2.0.0: resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} - pino-pretty@13.1.2: - resolution: {integrity: sha512-3cN0tCakkT4f3zo9RXDIhy6GTvtYD6bK4CRBLN9j3E/ePqN1tugAXD5rGVfoChW6s0hiek+eyYlLNqc/BG7vBQ==} + pino-abstract-transport@3.0.0: + resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} + + pino-pretty@13.1.3: + resolution: {integrity: sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==} hasBin: true pino-std-serializers@7.0.0: @@ -3021,15 +3022,15 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} - typebox@1.0.55: - resolution: {integrity: sha512-TP02wN0B6tDZngprrGVu/Z9s/QUyVEmR7VIg1yEOtsqyDdXXEoQPSfWdkD2PsA2lGLxu6GgwOTtGZVS9CAoERg==} + typebox@1.0.61: + resolution: {integrity: sha512-5KeeL5QoPBoYm8Z7tGR1Pw9FjWA75MLhVuiSMCRgtgTg/d2+kTvolFddhOUua9FxpIaqXznFPZcc3sl6cEpafw==} - typescript-eslint@8.48.0: - resolution: {integrity: sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==} + typescript-eslint@8.48.1: + resolution: {integrity: sha512-FbOKN1fqNoXp1hIl5KYpObVrp0mCn+CLgn479nmu2IsRMrx2vyv74MmsBLVlhg8qVwNFGbXSp8fh1zp8pEoC2A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3071,9 +3072,6 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - uri-js-replace@1.0.1: - resolution: {integrity: sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==} - uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -3088,8 +3086,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - uuidv7@1.0.2: - resolution: {integrity: sha512-8JQkH4ooXnm1JCIhqTMbtmdnYEn6oKukBxHn1Ic9878jMkL7daTI7anTExfY18VRCX7tcdn5quzvCb6EWrR8PA==} + uuidv7@1.1.0: + resolution: {integrity: sha512-2VNnOC0+XQlwogChUDzy6pe8GQEys9QFZBGOh54l6qVfwoCUwwRvk7rDTgaIsRgsF5GFa5oiNg8LqXE3jofBBg==} hasBin: true vary@1.1.2: @@ -3104,8 +3102,8 @@ packages: vite: optional: true - vite@7.2.4: - resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} + vite@7.2.6: + resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3238,8 +3236,8 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} hasBin: true @@ -3395,7 +3393,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.3': dependencies: ajv: 6.12.6 debug: 4.4.3(supports-color@10.2.2) @@ -3436,7 +3434,7 @@ snapshots: '@fastify/cookie@11.0.2': dependencies: - cookie: 1.0.2 + cookie: 1.1.1 fastify-plugin: 5.1.0 '@fastify/deepmerge@3.1.0': {} @@ -3477,7 +3475,7 @@ snapshots: '@fastify/proxy-addr@5.1.0': dependencies: '@fastify/forwarded': 3.0.1 - ipaddr.js: 2.2.0 + ipaddr.js: 2.3.0 '@fastify/send@4.1.0': dependencies: @@ -3487,14 +3485,14 @@ snapshots: http-errors: 2.0.1 mime: 3.0.0 - '@fastify/sensible@6.0.3': + '@fastify/sensible@6.0.4': dependencies: '@lukeed/ms': 2.0.2 dequal: 2.0.3 fastify-plugin: 5.1.0 forwarded: 0.2.0 http-errors: 2.0.1 - type-is: 1.6.18 + type-is: 2.0.1 vary: 1.1.2 '@fastify/static@8.3.0': @@ -3512,7 +3510,7 @@ snapshots: fastify-plugin: 5.1.0 openapi-types: 12.1.3 rfdc: 1.4.1 - yaml: 2.8.1 + yaml: 2.8.2 '@fastify/swagger@9.6.1': dependencies: @@ -3520,7 +3518,7 @@ snapshots: json-schema-resolver: 3.0.0 openapi-types: 12.1.3 rfdc: 1.4.1 - yaml: 2.8.1 + yaml: 2.8.2 transitivePeerDependencies: - supports-color @@ -3859,13 +3857,6 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@redocly/ajv@8.11.4': - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js-replace: 1.0.1 - '@redocly/ajv@8.17.1': dependencies: fast-deep-equal: 3.1.3 @@ -3873,14 +3864,14 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - '@redocly/cli@2.11.1(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)': + '@redocly/cli@2.12.1(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)': dependencies: '@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.34.0 - '@redocly/openapi-core': 2.11.1(ajv@8.17.1) - '@redocly/respect-core': 2.11.1(ajv@8.17.1) + '@redocly/openapi-core': 2.12.1(ajv@8.17.1) + '@redocly/respect-core': 2.12.1(ajv@8.17.1) abort-controller: 3.0.0 chokidar: 3.6.0 colorette: 1.4.0 @@ -3913,7 +3904,7 @@ snapshots: '@redocly/config@0.22.2': {} - '@redocly/config@0.38.0': + '@redocly/config@0.40.0': dependencies: json-schema-to-ts: 2.7.2 @@ -3931,11 +3922,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@redocly/openapi-core@2.11.1(ajv@8.17.1)': + '@redocly/openapi-core@2.12.1(ajv@8.17.1)': dependencies: '@redocly/ajv': 8.17.1 - '@redocly/config': 0.38.0 - ajv-formats: 2.1.1(ajv@8.17.1) + '@redocly/config': 0.40.0 + ajv-formats: 3.0.1(ajv@8.17.1) colorette: 1.4.0 js-levenshtein: 1.1.6 js-yaml: 4.1.1 @@ -3945,12 +3936,12 @@ snapshots: transitivePeerDependencies: - ajv - '@redocly/respect-core@2.11.1(ajv@8.17.1)': + '@redocly/respect-core@2.12.1(ajv@8.17.1)': dependencies: '@faker-js/faker': 7.6.0 '@noble/hashes': 1.8.0 - '@redocly/ajv': 8.11.4 - '@redocly/openapi-core': 2.11.1(ajv@8.17.1) + '@redocly/ajv': 8.17.1 + '@redocly/openapi-core': 2.12.1(ajv@8.17.1) better-ajv-errors: 1.2.0(ajv@8.17.1) colorette: 2.0.20 json-pointer: 0.6.2 @@ -4026,8 +4017,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true - '@sinclair/typebox@0.34.41': {} - '@socket.io/component-emitter@3.1.2': {} '@standard-schema/spec@1.0.0': {} @@ -4073,14 +4062,14 @@ snapshots: '@types/trusted-types@2.0.7': optional: true - '@typescript-eslint/eslint-plugin@8.48.0(@typescript-eslint/parser@8.48.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.48.0(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.48.0 - '@typescript-eslint/type-utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.48.0 + '@typescript-eslint/parser': 8.48.1(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.48.1 + '@typescript-eslint/type-utils': 8.48.1(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.48.1(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.48.1 eslint: 9.39.1 graphemer: 1.4.0 ignore: 7.0.5 @@ -4090,41 +4079,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.48.0(eslint@9.39.1)(typescript@5.9.3)': + '@typescript-eslint/parser@8.48.1(eslint@9.39.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.48.0 - '@typescript-eslint/types': 8.48.0 - '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.48.0 + '@typescript-eslint/scope-manager': 8.48.1 + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/typescript-estree': 8.48.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.48.1 debug: 4.4.3(supports-color@10.2.2) eslint: 9.39.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.48.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.48.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3) - '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/tsconfig-utils': 8.48.1(typescript@5.9.3) + '@typescript-eslint/types': 8.48.1 debug: 4.4.3(supports-color@10.2.2) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.48.0': + '@typescript-eslint/scope-manager@8.48.1': dependencies: - '@typescript-eslint/types': 8.48.0 - '@typescript-eslint/visitor-keys': 8.48.0 + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/visitor-keys': 8.48.1 - '@typescript-eslint/tsconfig-utils@8.48.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.48.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.48.0(eslint@9.39.1)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.48.1(eslint@9.39.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.48.0 - '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/typescript-estree': 8.48.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.48.1(eslint@9.39.1)(typescript@5.9.3) debug: 4.4.3(supports-color@10.2.2) eslint: 9.39.1 ts-api-utils: 2.1.0(typescript@5.9.3) @@ -4132,14 +4121,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.48.0': {} + '@typescript-eslint/types@8.48.1': {} - '@typescript-eslint/typescript-estree@8.48.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.48.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.48.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3) - '@typescript-eslint/types': 8.48.0 - '@typescript-eslint/visitor-keys': 8.48.0 + '@typescript-eslint/project-service': 8.48.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.48.1(typescript@5.9.3) + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/visitor-keys': 8.48.1 debug: 4.4.3(supports-color@10.2.2) minimatch: 9.0.5 semver: 7.7.3 @@ -4149,20 +4138,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.48.0(eslint@9.39.1)(typescript@5.9.3)': + '@typescript-eslint/utils@8.48.1(eslint@9.39.1)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) - '@typescript-eslint/scope-manager': 8.48.0 - '@typescript-eslint/types': 8.48.0 - '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.48.1 + '@typescript-eslint/types': 8.48.1 + '@typescript-eslint/typescript-estree': 8.48.1(typescript@5.9.3) eslint: 9.39.1 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.48.0': + '@typescript-eslint/visitor-keys@8.48.1': dependencies: - '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/types': 8.48.1 eslint-visitor-keys: 4.2.1 abort-controller@3.0.0: @@ -4184,10 +4173,6 @@ snapshots: agent-base@7.1.4: {} - ajv-formats@2.1.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 - ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -4446,9 +4431,11 @@ snapshots: dependencies: safe-buffer: 5.2.1 + content-type@1.0.5: {} + cookie@0.7.2: {} - cookie@1.0.2: {} + cookie@1.1.1: {} core-js@3.47.0: {} @@ -4656,7 +4643,7 @@ snapshots: '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.1 + '@eslint/eslintrc': 3.3.3 '@eslint/js': 9.39.1 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 @@ -4714,7 +4701,7 @@ snapshots: expand-template@2.0.3: {} - fast-copy@3.0.2: {} + fast-copy@4.0.0: {} fast-decode-uri-component@1.0.1: {} @@ -4769,7 +4756,7 @@ snapshots: generify: 4.2.0 help-me: 5.0.0 is-docker: 2.2.1 - pino-pretty: 13.1.2 + pino-pretty: 13.1.3 pkg-up: 3.1.0 resolve-from: 5.0.0 semver: 7.7.3 @@ -5058,7 +5045,7 @@ snapshots: ip-address@10.1.0: {} - ipaddr.js@2.2.0: {} + ipaddr.js@2.3.0: {} is-binary-path@2.1.0: dependencies: @@ -5167,7 +5154,7 @@ snapshots: light-my-request@6.6.0: dependencies: - cookie: 1.0.2 + cookie: 1.1.1 process-warning: 4.0.1 set-cookie-parser: 2.7.2 @@ -5179,7 +5166,7 @@ snapshots: nano-spawn: 2.0.0 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.8.1 + yaml: 2.8.2 listr2@9.0.5: dependencies: @@ -5224,7 +5211,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - lru-cache@11.2.2: {} + lru-cache@11.2.4: {} lru-cache@7.18.3: {} @@ -5240,7 +5227,7 @@ snapshots: math-intrinsics@1.1.0: {} - media-typer@0.3.0: {} + media-typer@1.1.0: {} micromatch@4.0.8: dependencies: @@ -5249,10 +5236,16 @@ snapshots: mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + mime@3.0.0: {} mimic-fn@2.1.0: {} @@ -5501,7 +5494,7 @@ snapshots: path-scurry@2.0.1: dependencies: - lru-cache: 11.2.2 + lru-cache: 11.2.4 minipass: 7.1.2 path-to-regexp@8.3.0: {} @@ -5520,17 +5513,21 @@ snapshots: dependencies: split2: 4.2.0 - pino-pretty@13.1.2: + pino-abstract-transport@3.0.0: + dependencies: + split2: 4.2.0 + + pino-pretty@13.1.3: dependencies: colorette: 2.0.20 dateformat: 4.6.3 - fast-copy: 3.0.2 + fast-copy: 4.0.0 fast-safe-stringify: 2.1.1 help-me: 5.0.0 joycon: 3.1.1 minimist: 1.2.8 on-exit-leak-free: 2.1.2 - pino-abstract-transport: 2.0.0 + pino-abstract-transport: 3.0.0 pump: 3.0.3 secure-json-parse: 4.1.0 sonic-boom: 4.2.0 @@ -6151,19 +6148,20 @@ snapshots: type-fest@4.41.0: {} - type-is@1.6.18: + type-is@2.0.1: dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 - typebox@1.0.55: {} + typebox@1.0.61: {} - typescript-eslint@8.48.0(eslint@9.39.1)(typescript@5.9.3): + typescript-eslint@8.48.1(eslint@9.39.1)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.48.0(@typescript-eslint/parser@8.48.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/parser': 8.48.0(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.48.1(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.48.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.48.1(eslint@9.39.1)(typescript@5.9.3) eslint: 9.39.1 typescript: 5.9.3 transitivePeerDependencies: @@ -6190,8 +6188,6 @@ snapshots: unpipe@1.0.0: {} - uri-js-replace@1.0.1: {} - uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -6204,22 +6200,22 @@ snapshots: util-deprecate@1.0.2: {} - uuidv7@1.0.2: {} + uuidv7@1.1.0: {} vary@1.1.2: {} - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@22.19.1)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.6(@types/node@22.19.1)(yaml@2.8.2)): dependencies: debug: 4.4.3(supports-color@10.2.2) globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.2.4(@types/node@22.19.1)(yaml@2.8.1) + vite: 7.2.6(@types/node@22.19.1)(yaml@2.8.2) transitivePeerDependencies: - supports-color - typescript - vite@7.2.4(@types/node@22.19.1)(yaml@2.8.1): + vite@7.2.6(@types/node@22.19.1)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -6230,9 +6226,9 @@ snapshots: optionalDependencies: '@types/node': 22.19.1 fsevents: 2.3.3 - yaml: 2.8.1 + yaml: 2.8.2 - vite@7.2.4(@types/node@24.10.1)(yaml@2.8.1): + vite@7.2.6(@types/node@24.10.1)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -6243,7 +6239,7 @@ snapshots: optionalDependencies: '@types/node': 24.10.1 fsevents: 2.3.3 - yaml: 2.8.1 + yaml: 2.8.2 walker@1.0.8: dependencies: @@ -6308,7 +6304,7 @@ snapshots: yaml@1.10.2: {} - yaml@2.8.1: {} + yaml@2.8.2: {} yargs-parser@20.2.9: {} diff --git a/src/user/package.json b/src/user/package.json index 4f197a3..6dfb965 100644 --- a/src/user/package.json +++ b/src/user/package.json @@ -21,17 +21,17 @@ "@fastify/autoload": "^6.3.1", "@fastify/formbody": "^8.0.2", "@fastify/multipart": "^9.3.0", - "@fastify/sensible": "^6.0.3", + "@fastify/sensible": "^6.0.4", "@fastify/static": "^8.3.0", "fastify": "^5.6.2", "fastify-cli": "^7.4.1", "fastify-plugin": "^5.1.0", - "typebox": "^1.0.55" + "typebox": "^1.0.61" }, "devDependencies": { "@types/node": "^22.19.1", "rollup-plugin-node-externals": "^8.1.2", - "vite": "^7.2.4", + "vite": "^7.2.6", "vite-tsconfig-paths": "^5.1.4" } }