feat: add comments functionality and integrate Socket.io for real-time updates

- Implemented a full comments module in the backend with repository, service, controller, and DTOs using NestJS.
- Added frontend support for comments with a `CommentSection` component and integration into content pages.
- Introduced `SocketProvider` on the frontend and integrated Socket.io for real-time communication.
- Updated dependencies and configurations for Socket.io and WebSockets support.
This commit is contained in:
Mathis HERRIOT
2026-01-29 14:33:34 +01:00
parent e73ae80fc5
commit 01117aad6d
14 changed files with 479 additions and 36 deletions

View File

@@ -36,8 +36,10 @@
"@nestjs/core": "^11.0.1", "@nestjs/core": "^11.0.1",
"@nestjs/mapped-types": "^2.1.0", "@nestjs/mapped-types": "^2.1.0",
"@nestjs/platform-express": "^11.0.1", "@nestjs/platform-express": "^11.0.1",
"@nestjs/platform-socket.io": "^11.1.12",
"@nestjs/schedule": "^6.1.0", "@nestjs/schedule": "^6.1.0",
"@nestjs/throttler": "^6.5.0", "@nestjs/throttler": "^6.5.0",
"@nestjs/websockets": "^11.1.12",
"@noble/post-quantum": "^0.5.4", "@noble/post-quantum": "^0.5.4",
"@node-rs/argon2": "^2.0.2", "@node-rs/argon2": "^2.0.2",
"@sentry/nestjs": "^10.32.1", "@sentry/nestjs": "^10.32.1",
@@ -48,6 +50,7 @@
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.3", "class-validator": "^0.14.3",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"drizzle-kit": "^0.31.8",
"drizzle-orm": "^0.45.1", "drizzle-orm": "^0.45.1",
"fluent-ffmpeg": "^2.1.3", "fluent-ffmpeg": "^2.1.3",
"helmet": "^8.1.0", "helmet": "^8.1.0",
@@ -61,23 +64,12 @@
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"sharp": "^0.34.5", "sharp": "^0.34.5",
"socket.io": "^4.8.3",
"uuid": "^13.0.0", "uuid": "^13.0.0",
"zod": "^4.3.5", "zod": "^4.3.5"
"drizzle-kit": "^0.31.8"
}, },
"devDependencies": { "devDependencies": {
"@nestjs/cli": "^11.0.0", "@nestjs/cli": "^11.0.0",
"globals": "^16.0.0",
"jest": "^30.0.0",
"source-map-support": "^0.5.21",
"supertest": "^7.0.0",
"ts-jest": "^29.2.5",
"ts-loader": "^9.5.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.21.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.20.0",
"@nestjs/schematics": "^11.0.0", "@nestjs/schematics": "^11.0.0",
"@nestjs/testing": "^11.0.1", "@nestjs/testing": "^11.0.1",
"@types/express": "^5.0.0", "@types/express": "^5.0.0",
@@ -89,9 +81,21 @@
"@types/pg": "^8.16.0", "@types/pg": "^8.16.0",
"@types/qrcode": "^1.5.6", "@types/qrcode": "^1.5.6",
"@types/sharp": "^0.32.0", "@types/sharp": "^0.32.0",
"@types/socket.io": "^3.0.2",
"@types/supertest": "^6.0.2", "@types/supertest": "^6.0.2",
"@types/uuid": "^11.0.0", "@types/uuid": "^11.0.0",
"drizzle-kit": "^0.31.8" "drizzle-kit": "^0.31.8",
"globals": "^16.0.0",
"jest": "^30.0.0",
"source-map-support": "^0.5.21",
"supertest": "^7.0.0",
"ts-jest": "^29.2.5",
"ts-loader": "^9.5.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.21.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.20.0"
}, },
"jest": { "jest": {
"moduleFileExtensions": [ "moduleFileExtensions": [

View File

@@ -10,6 +10,7 @@ import { AppController } from "./app.controller";
import { AppService } from "./app.service"; import { AppService } from "./app.service";
import { AuthModule } from "./auth/auth.module"; import { AuthModule } from "./auth/auth.module";
import { CategoriesModule } from "./categories/categories.module"; import { CategoriesModule } from "./categories/categories.module";
import { CommentsModule } from "./comments/comments.module";
import { CommonModule } from "./common/common.module"; import { CommonModule } from "./common/common.module";
import { CrawlerDetectionMiddleware } from "./common/middlewares/crawler-detection.middleware"; import { CrawlerDetectionMiddleware } from "./common/middlewares/crawler-detection.middleware";
import { HTTPLoggerMiddleware } from "./common/middlewares/http-logger.middleware"; import { HTTPLoggerMiddleware } from "./common/middlewares/http-logger.middleware";
@@ -21,7 +22,9 @@ import { FavoritesModule } from "./favorites/favorites.module";
import { HealthController } from "./health.controller"; import { HealthController } from "./health.controller";
import { MailModule } from "./mail/mail.module"; import { MailModule } from "./mail/mail.module";
import { MediaModule } from "./media/media.module"; import { MediaModule } from "./media/media.module";
import { MessagesModule } from "./messages/messages.module";
import { ReportsModule } from "./reports/reports.module"; import { ReportsModule } from "./reports/reports.module";
import { RealtimeModule } from "./realtime/realtime.module";
import { S3Module } from "./s3/s3.module"; import { S3Module } from "./s3/s3.module";
import { SessionsModule } from "./sessions/sessions.module"; import { SessionsModule } from "./sessions/sessions.module";
import { TagsModule } from "./tags/tags.module"; import { TagsModule } from "./tags/tags.module";
@@ -37,12 +40,15 @@ import { UsersModule } from "./users/users.module";
UsersModule, UsersModule,
AuthModule, AuthModule,
CategoriesModule, CategoriesModule,
CommentsModule,
ContentsModule, ContentsModule,
FavoritesModule, FavoritesModule,
TagsModule, TagsModule,
MediaModule, MediaModule,
MessagesModule,
SessionsModule, SessionsModule,
ReportsModule, ReportsModule,
RealtimeModule,
ApiKeysModule, ApiKeysModule,
AdminModule, AdminModule,
ScheduleModule.forRoot(), ScheduleModule.forRoot(),

View File

@@ -0,0 +1,41 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Req,
UseGuards,
} from "@nestjs/common";
import { AuthGuard } from "../auth/guards/auth.guard";
import type { AuthenticatedRequest } from "../common/interfaces/request.interface";
import { CommentsService } from "./comments.service";
import { CreateCommentDto } from "./dto/create-comment.dto";
@Controller()
export class CommentsController {
constructor(private readonly commentsService: CommentsService) {}
@Get("contents/:contentId/comments")
findAllByContentId(@Param("contentId") contentId: string) {
return this.commentsService.findAllByContentId(contentId);
}
@Post("contents/:contentId/comments")
@UseGuards(AuthGuard)
create(
@Req() req: AuthenticatedRequest,
@Param("contentId") contentId: string,
@Body() dto: CreateCommentDto,
) {
return this.commentsService.create(req.user.sub, contentId, dto);
}
@Delete("comments/:id")
@UseGuards(AuthGuard)
remove(@Req() req: AuthenticatedRequest, @Param("id") id: string) {
const isAdmin = req.user.role === "admin" || req.user.role === "moderator";
return this.commentsService.remove(req.user.sub, id, isAdmin);
}
}

View File

@@ -0,0 +1,13 @@
import { Module } from "@nestjs/common";
import { AuthModule } from "../auth/auth.module";
import { CommentsController } from "./comments.controller";
import { CommentsService } from "./comments.service";
import { CommentsRepository } from "./repositories/comments.repository";
@Module({
imports: [AuthModule],
controllers: [CommentsController],
providers: [CommentsService, CommentsRepository],
exports: [CommentsService],
})
export class CommentsModule {}

View File

@@ -0,0 +1,37 @@
import {
ForbiddenException,
Injectable,
NotFoundException,
} from "@nestjs/common";
import { CommentsRepository } from "./repositories/comments.repository";
import type { CreateCommentDto } from "./dto/create-comment.dto";
@Injectable()
export class CommentsService {
constructor(private readonly commentsRepository: CommentsRepository) {}
async create(userId: string, contentId: string, dto: CreateCommentDto) {
return this.commentsRepository.create({
userId,
contentId,
text: dto.text,
});
}
async findAllByContentId(contentId: string) {
return this.commentsRepository.findAllByContentId(contentId);
}
async remove(userId: string, commentId: string, isAdmin = false) {
const comment = await this.commentsRepository.findOne(commentId);
if (!comment) {
throw new NotFoundException("Comment not found");
}
if (!isAdmin && comment.userId !== userId) {
throw new ForbiddenException("You cannot delete this comment");
}
await this.commentsRepository.delete(commentId);
}
}

View File

@@ -0,0 +1,8 @@
import { IsNotEmpty, IsString, MaxLength } from "class-validator";
export class CreateCommentDto {
@IsString()
@IsNotEmpty()
@MaxLength(1000)
text!: string;
}

View File

@@ -0,0 +1,53 @@
import { Injectable } from "@nestjs/common";
import { and, desc, eq, isNull } from "drizzle-orm";
import { DatabaseService } from "../../database/database.service";
import { comments, users } from "../../database/schemas";
import type { NewCommentInDb } from "../../database/schemas/comments";
@Injectable()
export class CommentsRepository {
constructor(private readonly databaseService: DatabaseService) {}
async create(data: NewCommentInDb) {
const [comment] = await this.databaseService.db
.insert(comments)
.values(data)
.returning();
return comment;
}
async findAllByContentId(contentId: string) {
return this.databaseService.db
.select({
id: comments.id,
text: comments.text,
createdAt: comments.createdAt,
updatedAt: comments.updatedAt,
user: {
uuid: users.uuid,
username: users.username,
displayName: users.displayName,
avatarUrl: users.avatarUrl,
},
})
.from(comments)
.innerJoin(users, eq(comments.userId, users.uuid))
.where(and(eq(comments.contentId, contentId), isNull(comments.deletedAt)))
.orderBy(desc(comments.createdAt));
}
async findOne(id: string) {
const [comment] = await this.databaseService.db
.select()
.from(comments)
.where(and(eq(comments.id, id), isNull(comments.deletedAt)));
return comment;
}
async delete(id: string) {
await this.databaseService.db
.update(comments)
.set({ deletedAt: new Date() })
.where(eq(comments.id, id));
}
}

View File

@@ -0,0 +1,31 @@
import { index, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
import { contents } from "./content";
import { users } from "./users";
export const comments = pgTable(
"comments",
{
id: uuid("id").primaryKey().defaultRandom(),
contentId: uuid("content_id")
.notNull()
.references(() => contents.id, { onDelete: "cascade" }),
userId: uuid("user_id")
.notNull()
.references(() => users.uuid, { onDelete: "cascade" }),
text: text("text").notNull(),
createdAt: timestamp("created_at", { withTimezone: true })
.notNull()
.defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true })
.notNull()
.defaultNow(),
deletedAt: timestamp("deleted_at", { withTimezone: true }),
},
(table) => ({
contentIdIdx: index("comments_content_id_idx").on(table.contentId),
userIdIdx: index("comments_user_id_idx").on(table.userId),
}),
);
export type CommentInDb = typeof comments.$inferSelect;
export type NewCommentInDb = typeof comments.$inferInsert;

View File

@@ -1,11 +1,13 @@
export * from "./api_keys"; export * from "./api_keys";
export * from "./audit_logs"; export * from "./audit_logs";
export * from "./categories"; export * from "./categories";
export * from "./comments";
export * from "./content"; export * from "./content";
export * from "./favorites"; export * from "./favorites";
export * from "./pgp"; export * from "./pgp";
export * from "./rbac"; export * from "./rbac";
export * from "./reports"; export * from "./reports";
export * from "./messages";
export * from "./sessions"; export * from "./sessions";
export * from "./tags"; export * from "./tags";
export * from "./users"; export * from "./users";

View File

@@ -54,6 +54,7 @@
"react-hook-form": "^7.71.1", "react-hook-form": "^7.71.1",
"react-resizable-panels": "^4.4.1", "react-resizable-panels": "^4.4.1",
"recharts": "2.15.4", "recharts": "2.15.4",
"socket.io-client": "^4.8.3",
"sonner": "^2.0.7", "sonner": "^2.0.7",
"tailwind-merge": "^3.4.0", "tailwind-merge": "^3.4.0",
"vaul": "^1.1.2", "vaul": "^1.1.2",

View File

@@ -3,6 +3,7 @@ import type { Metadata } from "next";
import Link from "next/link"; import Link from "next/link";
import { notFound } from "next/navigation"; import { notFound } from "next/navigation";
import { ContentCard } from "@/components/content-card"; import { ContentCard } from "@/components/content-card";
import { CommentSection } from "@/components/comment-section";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { ViewCounter } from "@/components/view-counter"; import { ViewCounter } from "@/components/view-counter";
import { ContentService } from "@/services/content.service"; import { ContentService } from "@/services/content.service";
@@ -53,6 +54,7 @@ export default async function MemePage({
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 items-start"> <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 items-start">
<div className="lg:col-span-2"> <div className="lg:col-span-2">
<ContentCard content={content} /> <ContentCard content={content} />
<CommentSection contentId={content.id} />
</div> </div>
<div className="space-y-6"> <div className="space-y-6">

View File

@@ -3,6 +3,7 @@ import { Ubuntu_Mono, Ubuntu_Sans } from "next/font/google";
import { Toaster } from "@/components/ui/sonner"; import { Toaster } from "@/components/ui/sonner";
import { AudioProvider } from "@/providers/audio-provider"; import { AudioProvider } from "@/providers/audio-provider";
import { AuthProvider } from "@/providers/auth-provider"; import { AuthProvider } from "@/providers/auth-provider";
import { SocketProvider } from "@/providers/socket-provider";
import { ThemeProvider } from "@/providers/theme-provider"; import { ThemeProvider } from "@/providers/theme-provider";
import "./globals.css"; import "./globals.css";
@@ -72,10 +73,12 @@ export default function RootLayout({
disableTransitionOnChange disableTransitionOnChange
> >
<AuthProvider> <AuthProvider>
<AudioProvider> <SocketProvider>
{children} <AudioProvider>
<Toaster /> {children}
</AudioProvider> <Toaster />
</AudioProvider>
</SocketProvider>
</AuthProvider> </AuthProvider>
</ThemeProvider> </ThemeProvider>
</body> </body>

View File

@@ -10,6 +10,7 @@ import {
LayoutGrid, LayoutGrid,
LogIn, LogIn,
LogOut, LogOut,
MessageCircle,
PlusCircle, PlusCircle,
Settings, Settings,
ShieldCheck, ShieldCheck,
@@ -180,6 +181,20 @@ export function AppSidebar() {
</Link> </Link>
</SidebarMenuButton> </SidebarMenuButton>
</SidebarMenuItem> </SidebarMenuItem>
{isAuthenticated && (
<SidebarMenuItem>
<SidebarMenuButton
asChild
isActive={pathname === "/messages"}
tooltip="Messages"
>
<Link href="/messages">
<MessageCircle />
<span>Messages</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
)}
</SidebarMenu> </SidebarMenu>
</SidebarGroup> </SidebarGroup>

263
pnpm-lock.yaml generated
View File

@@ -28,19 +28,25 @@ importers:
version: 4.0.2(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) version: 4.0.2(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)
'@nestjs/core': '@nestjs/core':
specifier: ^11.0.1 specifier: ^11.0.1
version: 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) version: 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/mapped-types': '@nestjs/mapped-types':
specifier: ^2.1.0 specifier: ^2.1.0
version: 2.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2) version: 2.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)
'@nestjs/platform-express': '@nestjs/platform-express':
specifier: ^11.0.1 specifier: ^11.0.1
version: 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11) version: 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)
'@nestjs/platform-socket.io':
specifier: ^11.1.12
version: 11.1.12(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.12)(rxjs@7.8.2)
'@nestjs/schedule': '@nestjs/schedule':
specifier: ^6.1.0 specifier: ^6.1.0
version: 6.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11) version: 6.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)
'@nestjs/throttler': '@nestjs/throttler':
specifier: ^6.5.0 specifier: ^6.5.0
version: 6.5.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(reflect-metadata@0.2.2) version: 6.5.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(reflect-metadata@0.2.2)
'@nestjs/websockets':
specifier: ^11.1.12
version: 11.1.12(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(@nestjs/platform-socket.io@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@noble/post-quantum': '@noble/post-quantum':
specifier: ^0.5.4 specifier: ^0.5.4
version: 0.5.4 version: 0.5.4
@@ -113,6 +119,9 @@ importers:
sharp: sharp:
specifier: ^0.34.5 specifier: ^0.34.5
version: 0.34.5 version: 0.34.5
socket.io:
specifier: ^4.8.3
version: 4.8.3
uuid: uuid:
specifier: ^13.0.0 specifier: ^13.0.0
version: 13.0.0 version: 13.0.0
@@ -156,6 +165,9 @@ importers:
'@types/sharp': '@types/sharp':
specifier: ^0.32.0 specifier: ^0.32.0
version: 0.32.0 version: 0.32.0
'@types/socket.io':
specifier: ^3.0.2
version: 3.0.2
'@types/supertest': '@types/supertest':
specifier: ^6.0.2 specifier: ^6.0.2
version: 6.0.3 version: 6.0.3
@@ -388,6 +400,9 @@ importers:
recharts: recharts:
specifier: 2.15.4 specifier: 2.15.4
version: 2.15.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) version: 2.15.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
socket.io-client:
specifier: ^4.8.3
version: 4.8.3
sonner: sonner:
specifier: ^2.0.7 specifier: ^2.0.7
version: 2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3) version: 2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -2020,6 +2035,13 @@ packages:
'@nestjs/common': ^11.0.0 '@nestjs/common': ^11.0.0
'@nestjs/core': ^11.0.0 '@nestjs/core': ^11.0.0
'@nestjs/platform-socket.io@11.1.12':
resolution: {integrity: sha512-1itTTYsAZecrq2NbJOkch32y8buLwN7UpcNRdJrhlS+ovJ5GxLx3RyJ3KylwBhbYnO5AeYyL1U/i4W5mg/4qDA==}
peerDependencies:
'@nestjs/common': ^11.0.0
'@nestjs/websockets': ^11.0.0
rxjs: ^7.1.0
'@nestjs/schedule@6.1.0': '@nestjs/schedule@6.1.0':
resolution: {integrity: sha512-W25Ydc933Gzb1/oo7+bWzzDiOissE+h/dhIAPugA39b9MuIzBbLybuXpc1AjoQLczO3v0ldmxaffVl87W0uqoQ==} resolution: {integrity: sha512-W25Ydc933Gzb1/oo7+bWzzDiOissE+h/dhIAPugA39b9MuIzBbLybuXpc1AjoQLczO3v0ldmxaffVl87W0uqoQ==}
peerDependencies: peerDependencies:
@@ -2051,6 +2073,18 @@ packages:
'@nestjs/core': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 '@nestjs/core': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0
reflect-metadata: ^0.1.13 || ^0.2.0 reflect-metadata: ^0.1.13 || ^0.2.0
'@nestjs/websockets@11.1.12':
resolution: {integrity: sha512-ulSOYcgosx1TqY425cRC5oXtAu1R10+OSmVfgyR9ueR25k4luekURt8dzAZxhxSCI0OsDj9WKCFLTkEuAwg0wg==}
peerDependencies:
'@nestjs/common': ^11.0.0
'@nestjs/core': ^11.0.0
'@nestjs/platform-socket.io': ^11.0.0
reflect-metadata: ^0.1.12 || ^0.2.0
rxjs: ^7.1.0
peerDependenciesMeta:
'@nestjs/platform-socket.io':
optional: true
'@next/env@16.1.1': '@next/env@16.1.1':
resolution: {integrity: sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA==} resolution: {integrity: sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA==}
@@ -3513,6 +3547,9 @@ packages:
resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
'@socket.io/component-emitter@3.1.2':
resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
'@standard-schema/spec@1.1.0': '@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
@@ -3657,6 +3694,9 @@ packages:
'@types/cookiejar@2.1.5': '@types/cookiejar@2.1.5':
resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==}
'@types/cors@2.8.19':
resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==}
'@types/d3-array@3.2.2': '@types/d3-array@3.2.2':
resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==}
@@ -3879,6 +3919,10 @@ packages:
resolution: {integrity: sha512-OOi3kL+FZDnPhVzsfD37J88FNeZh6gQsGcLc95NbeURRGvmSjeXiDcyWzF2o3yh/gQAUn2uhh/e+CPCa5nwAxw==} resolution: {integrity: sha512-OOi3kL+FZDnPhVzsfD37J88FNeZh6gQsGcLc95NbeURRGvmSjeXiDcyWzF2o3yh/gQAUn2uhh/e+CPCa5nwAxw==}
deprecated: This is a stub types definition. sharp provides its own type definitions, so you do not need this installed. deprecated: This is a stub types definition. sharp provides its own type definitions, so you do not need this installed.
'@types/socket.io@3.0.2':
resolution: {integrity: sha512-pu0sN9m5VjCxBZVK8hW37ZcMe8rjn4HHggBN5CbaRTvFwv5jOmuIRZEuddsBPa9Th0ts0SIo3Niukq+95cMBbQ==}
deprecated: This is a stub types definition. socket.io provides its own type definitions, so you do not need this installed.
'@types/stack-utils@2.0.3': '@types/stack-utils@2.0.3':
resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
@@ -4139,6 +4183,10 @@ packages:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
accepts@1.3.8:
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
accepts@2.0.0: accepts@2.0.0:
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@@ -4331,6 +4379,10 @@ packages:
base64-js@1.5.1: base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
base64id@2.0.0:
resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
engines: {node: ^4.5.0 || >= 5.9}
baseline-browser-mapping@2.9.11: baseline-browser-mapping@2.9.11:
resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==}
hasBin: true hasBin: true
@@ -5192,6 +5244,17 @@ packages:
resolution: {integrity: sha512-EuJWwlHPZ1LbADuKTClvHtwbaFn4rOD+dRAbWysqEOXRc2Uui0hJInNJrsdH0c+OhJA4nrCBdSkW4DD5YxAo6A==} resolution: {integrity: sha512-EuJWwlHPZ1LbADuKTClvHtwbaFn4rOD+dRAbWysqEOXRc2Uui0hJInNJrsdH0c+OhJA4nrCBdSkW4DD5YxAo6A==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
engine.io-client@6.6.4:
resolution: {integrity: sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==}
engine.io-parser@5.2.3:
resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==}
engines: {node: '>=10.0.0'}
engine.io@6.6.5:
resolution: {integrity: sha512-2RZdgEbXmp5+dVbRm0P7HQUImZpICccJy7rN7Tv+SFa55pH+lxnuw6/K1ZxxBfHoYpSkHLAO92oa8O4SwFXA2A==}
engines: {node: '>=10.2.0'}
enhanced-resolve@5.18.4: enhanced-resolve@5.18.4:
resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
@@ -6850,6 +6913,10 @@ packages:
natural-compare@1.4.0: natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
negotiator@0.6.3:
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
engines: {node: '>= 0.6'}
negotiator@1.0.0: negotiator@1.0.0:
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@@ -6955,6 +7022,10 @@ packages:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
object-hash@3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
object-inspect@1.13.4: object-inspect@1.13.4:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@@ -7664,6 +7735,21 @@ packages:
slick@1.12.2: slick@1.12.2:
resolution: {integrity: sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==} resolution: {integrity: sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==}
socket.io-adapter@2.5.6:
resolution: {integrity: sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==}
socket.io-client@4.8.3:
resolution: {integrity: sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==}
engines: {node: '>=10.0.0'}
socket.io-parser@4.2.5:
resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==}
engines: {node: '>=10.0.0'}
socket.io@4.8.3:
resolution: {integrity: sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==}
engines: {node: '>=10.2.0'}
sonner@2.0.7: sonner@2.0.7:
resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==}
peerDependencies: peerDependencies:
@@ -8341,6 +8427,18 @@ packages:
resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
ws@8.18.3:
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
xml2js@0.6.2: xml2js@0.6.2:
resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==}
engines: {node: '>=4.0.0'} engines: {node: '>=4.0.0'}
@@ -8349,6 +8447,10 @@ packages:
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
engines: {node: '>=4.0'} engines: {node: '>=4.0'}
xmlhttprequest-ssl@2.1.2:
resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==}
engines: {node: '>=0.4.0'}
xtend@4.0.2: xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'} engines: {node: '>=0.4'}
@@ -9857,7 +9959,7 @@ snapshots:
dependencies: dependencies:
'@jest/fake-timers': 30.2.0 '@jest/fake-timers': 30.2.0
'@jest/types': 30.2.0 '@jest/types': 30.2.0
'@types/node': 22.19.6 '@types/node': 24.10.4
jest-mock: 30.2.0 jest-mock: 30.2.0
'@jest/expect-utils@30.2.0': '@jest/expect-utils@30.2.0':
@@ -9875,7 +9977,7 @@ snapshots:
dependencies: dependencies:
'@jest/types': 30.2.0 '@jest/types': 30.2.0
'@sinonjs/fake-timers': 13.0.5 '@sinonjs/fake-timers': 13.0.5
'@types/node': 22.19.6 '@types/node': 24.10.4
jest-message-util: 30.2.0 jest-message-util: 30.2.0
jest-mock: 30.2.0 jest-mock: 30.2.0
jest-util: 30.2.0 jest-util: 30.2.0
@@ -10063,7 +10165,7 @@ snapshots:
dependencies: dependencies:
'@css-inline/css-inline': 0.14.1 '@css-inline/css-inline': 0.14.1
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
glob: 10.3.12 glob: 10.3.12
nodemailer: 7.0.12 nodemailer: 7.0.12
optionalDependencies: optionalDependencies:
@@ -10082,7 +10184,7 @@ snapshots:
'@nestjs/cache-manager@3.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(cache-manager@7.2.7)(keyv@5.5.5)(rxjs@7.8.2)': '@nestjs/cache-manager@3.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(cache-manager@7.2.7)(keyv@5.5.5)(rxjs@7.8.2)':
dependencies: dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
cache-manager: 7.2.7 cache-manager: 7.2.7
keyv: 5.5.5 keyv: 5.5.5
rxjs: 7.8.2 rxjs: 7.8.2
@@ -10136,7 +10238,7 @@ snapshots:
lodash: 4.17.21 lodash: 4.17.21
rxjs: 7.8.2 rxjs: 7.8.2
'@nestjs/core@11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2)': '@nestjs/core@11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
dependencies: dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nuxt/opencollective': 0.4.1 '@nuxt/opencollective': 0.4.1
@@ -10149,6 +10251,7 @@ snapshots:
uid: 2.0.2 uid: 2.0.2
optionalDependencies: optionalDependencies:
'@nestjs/platform-express': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11) '@nestjs/platform-express': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)
'@nestjs/websockets': 11.1.12(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(@nestjs/platform-socket.io@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)': '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)':
dependencies: dependencies:
@@ -10161,7 +10264,7 @@ snapshots:
'@nestjs/platform-express@11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)': '@nestjs/platform-express@11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)':
dependencies: dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
cors: 2.8.5 cors: 2.8.5
express: 5.2.1 express: 5.2.1
multer: 2.0.2 multer: 2.0.2
@@ -10170,10 +10273,22 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@nestjs/platform-socket.io@11.1.12(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.12)(rxjs@7.8.2)':
dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/websockets': 11.1.12(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(@nestjs/platform-socket.io@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
rxjs: 7.8.2
socket.io: 4.8.3
tslib: 2.8.1
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@nestjs/schedule@6.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)': '@nestjs/schedule@6.1.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)':
dependencies: dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
cron: 4.3.5 cron: 4.3.5
'@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)': '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)':
@@ -10190,7 +10305,7 @@ snapshots:
'@nestjs/testing@11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(@nestjs/platform-express@11.1.11)': '@nestjs/testing@11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(@nestjs/platform-express@11.1.11)':
dependencies: dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
tslib: 2.8.1 tslib: 2.8.1
optionalDependencies: optionalDependencies:
'@nestjs/platform-express': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11) '@nestjs/platform-express': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)
@@ -10198,9 +10313,21 @@ snapshots:
'@nestjs/throttler@6.5.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(reflect-metadata@0.2.2)': '@nestjs/throttler@6.5.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(reflect-metadata@0.2.2)':
dependencies: dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
reflect-metadata: 0.2.2 reflect-metadata: 0.2.2
'@nestjs/websockets@11.1.12(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(@nestjs/platform-socket.io@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
iterare: 1.2.1
object-hash: 3.0.0
reflect-metadata: 0.2.2
rxjs: 7.8.2
tslib: 2.8.1
optionalDependencies:
'@nestjs/platform-socket.io': 11.1.12(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.12)(rxjs@7.8.2)
'@next/env@16.1.1': {} '@next/env@16.1.1': {}
'@next/swc-darwin-arm64@16.1.1': '@next/swc-darwin-arm64@16.1.1':
@@ -11380,7 +11507,7 @@ snapshots:
'@sentry/nestjs@10.32.1(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)': '@sentry/nestjs@10.32.1(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)':
dependencies: dependencies:
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.11)(@nestjs/websockets@11.1.12)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0)
@@ -11795,6 +11922,8 @@ snapshots:
dependencies: dependencies:
tslib: 2.8.1 tslib: 2.8.1
'@socket.io/component-emitter@3.1.2': {}
'@standard-schema/spec@1.1.0': {} '@standard-schema/spec@1.1.0': {}
'@standard-schema/utils@0.3.0': {} '@standard-schema/utils@0.3.0': {}
@@ -11926,6 +12055,10 @@ snapshots:
'@types/cookiejar@2.1.5': {} '@types/cookiejar@2.1.5': {}
'@types/cors@2.8.19':
dependencies:
'@types/node': 24.10.4
'@types/d3-array@3.2.2': {} '@types/d3-array@3.2.2': {}
'@types/d3-axis@3.0.6': '@types/d3-axis@3.0.6':
@@ -12134,7 +12267,7 @@ snapshots:
'@types/mysql@2.15.27': '@types/mysql@2.15.27':
dependencies: dependencies:
'@types/node': 22.19.6 '@types/node': 24.10.4
'@types/node@20.19.27': '@types/node@20.19.27':
dependencies: dependencies:
@@ -12161,7 +12294,7 @@ snapshots:
'@types/pg@8.15.6': '@types/pg@8.15.6':
dependencies: dependencies:
'@types/node': 22.19.6 '@types/node': 24.10.4
pg-protocol: 1.10.3 pg-protocol: 1.10.3
pg-types: 2.2.0 pg-types: 2.2.0
@@ -12203,6 +12336,14 @@ snapshots:
dependencies: dependencies:
sharp: 0.34.5 sharp: 0.34.5
'@types/socket.io@3.0.2':
dependencies:
socket.io: 4.8.3
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@types/stack-utils@2.0.3': {} '@types/stack-utils@2.0.3': {}
'@types/superagent@8.1.9': '@types/superagent@8.1.9':
@@ -12219,7 +12360,7 @@ snapshots:
'@types/tedious@4.0.14': '@types/tedious@4.0.14':
dependencies: dependencies:
'@types/node': 22.19.6 '@types/node': 24.10.4
'@types/trusted-types@2.0.7': '@types/trusted-types@2.0.7':
optional: true optional: true
@@ -12485,6 +12626,11 @@ snapshots:
abbrev@2.0.0: abbrev@2.0.0:
optional: true optional: true
accepts@1.3.8:
dependencies:
mime-types: 2.1.35
negotiator: 0.6.3
accepts@2.0.0: accepts@2.0.0:
dependencies: dependencies:
mime-types: 3.0.2 mime-types: 3.0.2
@@ -12681,6 +12827,8 @@ snapshots:
base64-js@1.5.1: {} base64-js@1.5.1: {}
base64id@2.0.0: {}
baseline-browser-mapping@2.9.11: {} baseline-browser-mapping@2.9.11: {}
binary-extensions@2.3.0: binary-extensions@2.3.0:
@@ -13511,6 +13659,36 @@ snapshots:
encoding-japanese@2.2.0: encoding-japanese@2.2.0:
optional: true optional: true
engine.io-client@6.6.4:
dependencies:
'@socket.io/component-emitter': 3.1.2
debug: 4.4.3
engine.io-parser: 5.2.3
ws: 8.18.3
xmlhttprequest-ssl: 2.1.2
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
engine.io-parser@5.2.3: {}
engine.io@6.6.5:
dependencies:
'@types/cors': 2.8.19
'@types/node': 24.10.4
accepts: 1.3.8
base64id: 2.0.0
cookie: 0.7.2
cors: 2.8.5
debug: 4.4.3
engine.io-parser: 5.2.3
ws: 8.18.3
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
enhanced-resolve@5.18.4: enhanced-resolve@5.18.4:
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
@@ -14604,7 +14782,7 @@ snapshots:
'@jest/expect': 30.2.0 '@jest/expect': 30.2.0
'@jest/test-result': 30.2.0 '@jest/test-result': 30.2.0
'@jest/types': 30.2.0 '@jest/types': 30.2.0
'@types/node': 22.19.6 '@types/node': 24.10.4
chalk: 4.1.2 chalk: 4.1.2
co: 4.6.0 co: 4.6.0
dedent: 1.7.1 dedent: 1.7.1
@@ -14701,7 +14879,7 @@ snapshots:
'@jest/environment': 30.2.0 '@jest/environment': 30.2.0
'@jest/fake-timers': 30.2.0 '@jest/fake-timers': 30.2.0
'@jest/types': 30.2.0 '@jest/types': 30.2.0
'@types/node': 22.19.6 '@types/node': 24.10.4
jest-mock: 30.2.0 jest-mock: 30.2.0
jest-util: 30.2.0 jest-util: 30.2.0
jest-validate: 30.2.0 jest-validate: 30.2.0
@@ -14886,13 +15064,13 @@ snapshots:
jest-worker@27.5.1: jest-worker@27.5.1:
dependencies: dependencies:
'@types/node': 22.19.6 '@types/node': 24.10.4
merge-stream: 2.0.0 merge-stream: 2.0.0
supports-color: 8.1.1 supports-color: 8.1.1
jest-worker@30.2.0: jest-worker@30.2.0:
dependencies: dependencies:
'@types/node': 22.19.6 '@types/node': 24.10.4
'@ungap/structured-clone': 1.3.0 '@ungap/structured-clone': 1.3.0
jest-util: 30.2.0 jest-util: 30.2.0
merge-stream: 2.0.0 merge-stream: 2.0.0
@@ -16078,6 +16256,8 @@ snapshots:
natural-compare@1.4.0: {} natural-compare@1.4.0: {}
negotiator@0.6.3: {}
negotiator@1.0.0: {} negotiator@1.0.0: {}
neo-async@2.6.2: {} neo-async@2.6.2: {}
@@ -16173,6 +16353,8 @@ snapshots:
object-assign@4.1.1: {} object-assign@4.1.1: {}
object-hash@3.0.0: {}
object-inspect@1.13.4: {} object-inspect@1.13.4: {}
on-finished@2.4.1: on-finished@2.4.1:
@@ -17110,6 +17292,47 @@ snapshots:
slick@1.12.2: slick@1.12.2:
optional: true optional: true
socket.io-adapter@2.5.6:
dependencies:
debug: 4.4.3
ws: 8.18.3
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
socket.io-client@4.8.3:
dependencies:
'@socket.io/component-emitter': 3.1.2
debug: 4.4.3
engine.io-client: 6.6.4
socket.io-parser: 4.2.5
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
socket.io-parser@4.2.5:
dependencies:
'@socket.io/component-emitter': 3.1.2
debug: 4.4.3
transitivePeerDependencies:
- supports-color
socket.io@4.8.3:
dependencies:
accepts: 1.3.8
base64id: 2.0.0
cors: 2.8.5
debug: 4.4.3
engine.io: 6.6.5
socket.io-adapter: 2.5.6
socket.io-parser: 4.2.5
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
sonner@2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3): sonner@2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
dependencies: dependencies:
react: 19.2.3 react: 19.2.3
@@ -17812,6 +18035,8 @@ snapshots:
imurmurhash: 0.1.4 imurmurhash: 0.1.4
signal-exit: 4.1.0 signal-exit: 4.1.0
ws@8.18.3: {}
xml2js@0.6.2: xml2js@0.6.2:
dependencies: dependencies:
sax: 1.4.3 sax: 1.4.3
@@ -17819,6 +18044,8 @@ snapshots:
xmlbuilder@11.0.1: {} xmlbuilder@11.0.1: {}
xmlhttprequest-ssl@2.1.2: {}
xtend@4.0.2: {} xtend@4.0.2: {}
y18n@4.0.3: {} y18n@4.0.3: {}