diff --git a/.env.example b/.env.example index 1aa2b7b..929eed4 100644 --- a/.env.example +++ b/.env.example @@ -6,3 +6,5 @@ AUTH_TRUST_HOST="" MAILCHIMP_API_KEY="" MAILCHIMP_LIST_ID="" REDIS_URL="" +NOVU_SECRET_KEY="" +NEXT_PUBLIC_NOVU_APP_ID="" \ No newline at end of file diff --git a/.github/workflows/novu.yml b/.github/workflows/novu.yml new file mode 100644 index 0000000..27abcec --- /dev/null +++ b/.github/workflows/novu.yml @@ -0,0 +1,15 @@ +# .github/workflows/novu.yml +name: Novu Sync + +on: + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Sync State to Novu + uses: novuhq/actions-novu-sync@v2 + with: + secret-key: ${{ secrets.NOVU_SECRET_KEY }} + bridge-url: \ No newline at end of file diff --git a/apps/frontend/src/app/api/dashboard/messages/route.tsx b/apps/frontend/src/app/api/dashboard/messages/route.tsx index f317567..9ae5d51 100644 --- a/apps/frontend/src/app/api/dashboard/messages/route.tsx +++ b/apps/frontend/src/app/api/dashboard/messages/route.tsx @@ -1,5 +1,8 @@ -import { auth } from "@frontend/auth"; -import { prisma } from "@db/prisma"; +import { auth } from '@frontend/auth'; +import { prisma } from '@db/prisma'; +import { Novu } from '@novu/node'; + +const novu = new Novu(process.env['NOVU_SECRET_KEY'] as string); export const GET = auth(async (req, res) => { const findSquad = await prisma.user.findFirst({ @@ -16,7 +19,7 @@ export const GET = auth(async (req, res) => { squadId: findSquad?.squadId!, }, orderBy: { - createdAt: "asc", + createdAt: 'asc', }, select: { id: true, @@ -27,8 +30,8 @@ export const GET = auth(async (req, res) => { name: true, profilePicture: true, handle: true, - } - } + }, + }, }, }); @@ -38,7 +41,7 @@ export const GET = auth(async (req, res) => { export const POST = auth(async (req, res) => { const body = await req?.json(); if (!body.message || body.message.length < 3) { - return Response.json({ message: "Message is required" }); + return Response.json({ message: 'Message is required' }); } const findSquad = await prisma.user.findFirst({ @@ -50,7 +53,38 @@ export const POST = auth(async (req, res) => { }, }); - await prisma.squadMessages.create({ + const squadeUsersAndSquadName = await prisma.squad.findFirst({ + where: { + id: findSquad?.squadId!, + }, + select: { + members: true, + name: true, + }, + }); + + const novuSubscribers = squadeUsersAndSquadName?.members.map((member) => { + const firstName = member?.name?.split(' ')[0]; + const lastName = member?.name?.split(' ')[1] ?? null; + return { + subscriberId: member.id, + email: member.email, + firstName: firstName, + lastName: lastName, + }; + }) as []; + + console.log(novuSubscribers); + if (novuSubscribers.length) { + await novu.trigger('devfest-chat-message', { + to: novuSubscribers, + payload: { + message: `Your **${squadeUsersAndSquadName?.name}** squad has a new message - **${body.message}**`, + }, + }); + } + + await await prisma.squadMessages.create({ data: { squadId: findSquad?.squadId!, message: body.message!, @@ -58,5 +92,5 @@ export const POST = auth(async (req, res) => { }, }); - return Response.json({ message: "Added" }); + return Response.json({ message: 'Added' }); }); diff --git a/apps/frontend/src/auth.ts b/apps/frontend/src/auth.ts index 7d7b35b..71a7642 100644 --- a/apps/frontend/src/auth.ts +++ b/apps/frontend/src/auth.ts @@ -1,12 +1,12 @@ -import NextAuth from "next-auth"; -import GitHub from "next-auth/providers/github"; -import { PrismaAdapter } from "@auth/prisma-adapter"; +import NextAuth from 'next-auth'; +import GitHub from 'next-auth/providers/github'; +import { PrismaAdapter } from '@auth/prisma-adapter'; import { prisma } from '@db/prisma'; export const { handlers, signIn, signOut, auth } = NextAuth({ adapter: PrismaAdapter(prisma), providers: [GitHub], - session: { strategy: "jwt" }, + session: { strategy: 'jwt' }, cookies: { pkceCodeVerifier: { name: 'next-auth.pkce.code_verifier', @@ -20,7 +20,7 @@ export const { handlers, signIn, signOut, auth } = NextAuth({ }, callbacks: { async jwt({ token, user, trigger, session, account }) { - if (trigger === "update" && session?.color) { + if (trigger === 'update' && session?.color) { token.color = session.color; } if (user) { @@ -38,31 +38,31 @@ export const { handlers, signIn, signOut, auth } = NextAuth({ token.isMod = user.isMod; } - if (trigger === "signUp") { - const [key, country] = process.env.MAILCHIMP_API_KEY!.split("-"); - const [name, lastName] = user?.name?.split(" ")!; + if (trigger === 'signUp') { + // const [key, country] = process.env.MAILCHIMP_API_KEY!.split("-"); + // const [name, lastName] = user?.name?.split(" ")!; - await fetch( - `https://${country}.api.mailchimp.com/3.0/lists/${process.env.MAILCHIMP_LIST_ID}/members`, - { - method: "POST", - headers: { - Authorization: `Basic ${Buffer.from("nevo:" + key).toString("base64")}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email_address: user.email, - status: "subscribed", - merge_fields: { - FNAME: name || "", - LNAME: lastName || "", - }, - }), - }, - ); + // await fetch( + // `https://${country}.api.mailchimp.com/3.0/lists/${process.env.MAILCHIMP_LIST_ID}/members`, + // { + // method: "POST", + // headers: { + // Authorization: `Basic ${Buffer.from("nevo:" + key).toString("base64")}`, + // "Content-Type": "application/json", + // }, + // body: JSON.stringify({ + // email_address: user.email, + // status: "subscribed", + // merge_fields: { + // FNAME: name || "", + // LNAME: lastName || "", + // }, + // }), + // }, + // ); const { login, avatar_url } = await ( - await fetch("https://api.github.com/user", { + await fetch('https://api.github.com/user', { headers: { Authorization: `Bearer ${account?.access_token}`, }, @@ -104,16 +104,16 @@ export const { handlers, signIn, signOut, auth } = NextAuth({ }, authorized: async ({ auth, request }) => { // Logged in users are authenticated, otherwise redirect to login page - if (!auth && request.url.indexOf("/api") > -1) { + if (!auth && request.url.indexOf('/api') > -1) { return Response.json( - { message: "You have to login" }, + { message: 'You have to login' }, { status: 401, - }, + } ); } if (!auth) { - return Response.redirect(new URL("/", request.url)); + return Response.redirect(new URL('/', request.url)); } return true; diff --git a/apps/frontend/src/components/dashboard/chat.tsx b/apps/frontend/src/components/dashboard/chat.tsx index 3a1ab82..b63450f 100644 --- a/apps/frontend/src/components/dashboard/chat.tsx +++ b/apps/frontend/src/components/dashboard/chat.tsx @@ -20,13 +20,15 @@ const SendMessage: FC<{ update: () => void }> = (props) => { const submit = useCallback( async (e: any) => { e.preventDefault(); + if (value.length < 3) { + return alert('You have to type at least 3 characters'); + } + await fetch('/api/dashboard/messages', { method: 'POST', body: JSON.stringify({ message: value }), }); - if (value.length < 3) { - return alert('You have to type at least 3 characters'); - } + setValue(''); props.update(); }, @@ -128,7 +130,10 @@ export function Chat() {

Make sure you create your{' '} - + personal ticket {' '} and share it. diff --git a/apps/frontend/src/components/layout/wrapper.tsx b/apps/frontend/src/components/layout/wrapper.tsx index 9e31833..a79e3e5 100644 --- a/apps/frontend/src/components/layout/wrapper.tsx +++ b/apps/frontend/src/components/layout/wrapper.tsx @@ -11,6 +11,7 @@ import { Footer } from '@frontend/sections'; import { useSession, signOut } from 'next-auth/react'; import { Toaster } from 'react-hot-toast'; import dynamic from 'next/dynamic'; +import { NotificationBell } from '../notification/novu'; import clsx from 'clsx'; const ShowEvent = dynamic(() => import('@frontend/utils/show.event'), { @@ -123,6 +124,15 @@ export const Wrapper = ({ children }: { children: ReactNode }) => { )} + {session.status == 'authenticated' && ( + + )} {session.status == 'authenticated' && (
  • signOut()} diff --git a/apps/frontend/src/components/notification/novu.tsx b/apps/frontend/src/components/notification/novu.tsx new file mode 100644 index 0000000..01d0e2d --- /dev/null +++ b/apps/frontend/src/components/notification/novu.tsx @@ -0,0 +1,22 @@ +'use client'; +import { Inbox } from '@novu/react'; +import { dark } from '@novu/react/themes'; + +export const NotificationBell = ({ userId }: { userId: string }) => { + console.log('userId', userId); + return ( + + ); +}; diff --git a/apps/frontend/src/styles/globals.css b/apps/frontend/src/styles/globals.css index 2d35a62..68fb6f2 100644 --- a/apps/frontend/src/styles/globals.css +++ b/apps/frontend/src/styles/globals.css @@ -100,3 +100,9 @@ h6 { .little-black { background: rgba(0, 0, 0, 0.9); } +.novu-popover-trigger { background-color: white;} +.novu-popover-trigger:hover { background-color: #A489FF;} + +.novu-bell-container > svg > path { + fill: black; +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 05b4b24..78cbce5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,11 +7,14 @@ "": { "name": "devfest", "version": "0.0.0", + "hasInstallScript": true, "license": "MIT", "dependencies": { "@nestjs/common": "^10.0.2", "@nestjs/core": "^10.0.2", "@nestjs/platform-express": "^10.0.2", + "@novu/node": "^2.0.1", + "@novu/react": "^2.3.0", "@octokit/graphql": "^7.0.1", "@prisma/client": "^5.19.0", "@sweetalert2/themes": "^5.0.18", @@ -45,7 +48,8 @@ "sweetalert2": "^11.14.0", "swr": "^2.2.5", "tslib": "^2.3.0", - "use-debounce": "^10.0.3" + "use-debounce": "^10.0.3", + "zod": "^3.23.8" }, "devDependencies": { "@auth/prisma-adapter": "^2.4.2", @@ -2220,7 +2224,6 @@ "version": "7.25.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2502,6 +2505,28 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "dependencies": { + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", + "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -3082,6 +3107,11 @@ "node": ">=8" } }, + "node_modules/@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==" + }, "node_modules/@module-federation/bridge-react-webpack-plugin": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.6.3.tgz", @@ -3325,6 +3355,64 @@ "@module-federation/sdk": "0.6.3" } }, + "node_modules/@motionone/animation": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", + "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", + "dependencies": { + "@motionone/easing": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/dom": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.18.0.tgz", + "integrity": "sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A==", + "dependencies": { + "@motionone/animation": "^10.18.0", + "@motionone/generators": "^10.18.0", + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/easing": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", + "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", + "dependencies": { + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/generators": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz", + "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", + "dependencies": { + "@motionone/types": "^10.17.1", + "@motionone/utils": "^10.18.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/types": { + "version": "10.17.1", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz", + "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==" + }, + "node_modules/@motionone/utils": { + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz", + "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", + "dependencies": { + "@motionone/types": "^10.17.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", @@ -3483,6 +3571,25 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/@nestjs/mapped-types": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz", + "integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==", + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/platform-express": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.1.tgz", @@ -3530,6 +3637,54 @@ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true }, + "node_modules/@nestjs/swagger": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", + "integrity": "sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==", + "dependencies": { + "@microsoft/tsdoc": "^0.15.0", + "@nestjs/mapped-types": "2.0.5", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "path-to-regexp": "3.2.0", + "swagger-ui-dist": "5.17.14" + }, + "peerDependencies": { + "@fastify/static": "^6.0.0 || ^7.0.0", + "@nestjs/common": "^9.0.0 || ^10.0.0", + "@nestjs/core": "^9.0.0 || ^10.0.0", + "class-transformer": "*", + "class-validator": "*", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "@fastify/static": { + "optional": true + }, + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, + "node_modules/@nestjs/swagger/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@nestjs/swagger/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@nestjs/testing": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.1.tgz", @@ -3796,6 +3951,90 @@ "node": ">=12.4.0" } }, + "node_modules/@novu/client": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@novu/client/-/client-2.0.0.tgz", + "integrity": "sha512-OAyoIJ+mGJsQRFsaRZL53jwuaPK/DsFGXQqlgNpfx+uCIxJHepqy9XmuaZNjxmRdylDBmombbHn+BB5sdqdrVw==", + "dependencies": { + "@novu/shared": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@novu/js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@novu/js/-/js-2.3.0.tgz", + "integrity": "sha512-HkLeWa1L/adizBManmQETsWifJCgRydUiEd4AKVp7ACiKLGhabTfU7VyzMKOC1+WQ+266e39mYcWkSdm/lkrEw==", + "dependencies": { + "@floating-ui/dom": "^1.6.7", + "@novu/client": "^2.0.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "mitt": "^3.0.1", + "socket.io-client": "4.7.2", + "solid-floating-ui": "^0.3.1", + "solid-js": "^1.8.11", + "solid-motionone": "^1.0.1", + "tailwind-merge": "^2.4.0" + } + }, + "node_modules/@novu/node": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@novu/node/-/node-2.0.1.tgz", + "integrity": "sha512-YIVo375oSV0UZfBOvLJr6heMxHf8MiJqcC0a3XAIgMofizBszcl0AS8+Z0ejukeZBomaX8z1q74JMbIMGc4FhA==", + "dependencies": { + "@novu/shared": "^2.0.1", + "axios": "^1.6.8", + "axios-retry": "^3.8.0", + "handlebars": "^4.7.7", + "lodash.get": "^4.4.2", + "lodash.merge": "^4.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@novu/node/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@novu/react": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@novu/react/-/react-2.3.0.tgz", + "integrity": "sha512-UQLD1nm2KX2n0p6iztAQwOJwqInbKcV23gF6ESaEhMG0TcyiLCNfhcpBmL5QXK/0xEzwsvMJmtXcYdU0NQWmLg==", + "dependencies": { + "@novu/js": "^2.3.0" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/@novu/shared": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@novu/shared/-/shared-2.1.1.tgz", + "integrity": "sha512-jwwtFezpy7ofTQJ9ibatcUzz163/KHqhwDSYWFEbBc4HNYPONyyBZHZGZAnqaJVH4tnIBS+F+iTl90+zszdkOQ==", + "dependencies": { + "@nestjs/swagger": "7.4.0", + "class-transformer": "0.5.1", + "class-validator": "0.14.1" + } + }, "node_modules/@nrwl/devkit": { "version": "19.7.2", "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-19.7.2.tgz", @@ -4759,6 +4998,49 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" + }, + "node_modules/@solid-primitives/props": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@solid-primitives/props/-/props-3.1.11.tgz", + "integrity": "sha512-jZAKWwvDRHjiydIumDgMj68qviIbowQ1ci7nkEAgzgvanNkhKSQV8iPgR2jMk1uv7S2ZqXYHslVQTgJel/TEyg==", + "dependencies": { + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/refs": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@solid-primitives/refs/-/refs-1.0.8.tgz", + "integrity": "sha512-+jIsWG8/nYvhaCoG2Vg6CJOLgTmPKFbaCrNQKWfChalgUf9WrVxWw0CdJb3yX15n5lUcQ0jBo6qYtuVVmBLpBw==", + "dependencies": { + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/transition-group": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@solid-primitives/transition-group/-/transition-group-1.0.5.tgz", + "integrity": "sha512-G3FuqvL13kQ55WzWPX2ewiXdZ/1iboiX53195sq7bbkDbXqP6TYKiadwEdsaDogW5rPnPYAym3+xnsNplQJRKQ==", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/utils": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.3.tgz", + "integrity": "sha512-CqAwKb2T5Vi72+rhebSsqNZ9o67buYRdEJrIFzRXz3U59QqezuuxPsyzTSVCacwS5Pf109VRsgCJQoxKRoECZQ==", + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", @@ -5907,6 +6189,11 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, + "node_modules/@types/validator": { + "version": "13.12.2", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.2.tgz", + "integrity": "sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==" + }, "node_modules/@types/ws": { "version": "8.5.12", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", @@ -6903,6 +7190,15 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/axios-retry": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", + "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "is-retry-allowed": "^2.2.0" + } + }, "node_modules/axobject-query": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.4.tgz", @@ -7618,6 +7914,40 @@ "integrity": "sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g==", "dev": true }, + "node_modules/class-transformer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" + }, + "node_modules/class-validator": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz", + "integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==", + "dependencies": { + "@types/validator": "^13.11.8", + "libphonenumber-js": "^1.10.53", + "validator": "^13.9.0" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/cli-color": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", @@ -9171,6 +9501,26 @@ "once": "^1.4.0" } }, + "node_modules/engine.io-client": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz", + "integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.17.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", @@ -11598,6 +11948,26 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/harmony-reflect": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", @@ -11707,6 +12077,11 @@ "he": "bin/he" } }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -12690,6 +13065,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-retry-allowed": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", + "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-set": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", @@ -14179,6 +14565,11 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.11.9.tgz", + "integrity": "sha512-Zs5wf5HaWzW2/inlupe2tstl0I/Tbqo7lH20ZLr6Is58u7Dz2n+gRFGNlj9/gWxFvNfp9+YyDsiegjNhdixB9A==" + }, "node_modules/license-webpack-plugin": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", @@ -14274,6 +14665,11 @@ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, "node_modules/lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -14288,8 +14684,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.uniq": { "version": "4.5.0", @@ -14610,6 +15005,11 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -14768,8 +15168,7 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/next": { "version": "14.2.3", @@ -16916,8 +17315,7 @@ "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regenerator-transform": { "version": "0.15.2", @@ -17457,6 +17855,25 @@ "randombytes": "^2.1.0" } }, + "node_modules/seroval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.1.1.tgz", + "integrity": "sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/seroval-plugins": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.1.1.tgz", + "integrity": "sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "seroval": "^1.0" + } + }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -17686,6 +18103,32 @@ "tslib": "^2.0.3" } }, + "node_modules/socket.io-client": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", + "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -17697,6 +18140,48 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/solid-floating-ui": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/solid-floating-ui/-/solid-floating-ui-0.3.1.tgz", + "integrity": "sha512-o/QmGsWPS2Z3KidAxP0nDvN7alI7Kqy0kU+wd85Fz+au5SYcnYm7I6Fk3M60Za35azsPX0U+5fEtqfOuk6Ao0Q==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.5", + "solid-js": "^1.8" + } + }, + "node_modules/solid-js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.1.tgz", + "integrity": "sha512-Gd6QWRFfO2XKKZqVK4YwbhWZkr0jWw1dYHOt+VYebomeyikGP0SuMflf42XcDuU9HAEYDArFJIYsBNjlE7iZsw==", + "dependencies": { + "csstype": "^3.1.0", + "seroval": "^1.1.0", + "seroval-plugins": "^1.1.0" + } + }, + "node_modules/solid-motionone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/solid-motionone/-/solid-motionone-1.0.2.tgz", + "integrity": "sha512-nMdfTZND5FzZSD5gcaSmjjgF7aldMmk4PHC88rUSSdUcrCP/LlVl0xMoy/qncQihgkqHRW0ywewbpE/+ToEibA==", + "dependencies": { + "@motionone/dom": "^10.17.0", + "@motionone/utils": "^10.17.0", + "@solid-primitives/props": "^3.1.11", + "@solid-primitives/refs": "^1.0.8", + "@solid-primitives/transition-group": "^1.0.5", + "csstype": "^3.1.3" + }, + "engines": { + "node": ">=20", + "pnpm": ">=9.0.0" + }, + "peerDependencies": { + "solid-js": "^1.8.0" + } + }, "node_modules/sorted-array-functions": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", @@ -17706,7 +18191,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -18407,6 +18891,11 @@ "url": "https://opencollective.com/svgo" } }, + "node_modules/swagger-ui-dist": { + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==" + }, "node_modules/sweetalert2": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.14.0.tgz", @@ -18434,6 +18923,15 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/tailwind-merge": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz", + "integrity": "sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", @@ -19243,6 +19741,18 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/uid": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", @@ -19483,6 +19993,14 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -20155,6 +20673,11 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -20211,7 +20734,6 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true, "engines": { "node": ">=10.0.0" }, @@ -20243,6 +20765,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -20331,6 +20861,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index d082fa0..947fadd 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "@nestjs/common": "^10.0.2", "@nestjs/core": "^10.0.2", "@nestjs/platform-express": "^10.0.2", + "@novu/node": "^2.0.1", + "@novu/react": "^2.3.0", "@octokit/graphql": "^7.0.1", "@prisma/client": "^5.19.0", "@sweetalert2/themes": "^5.0.18", @@ -49,7 +51,8 @@ "sweetalert2": "^11.14.0", "swr": "^2.2.5", "tslib": "^2.3.0", - "use-debounce": "^10.0.3" + "use-debounce": "^10.0.3", + "zod": "^3.23.8" }, "devDependencies": { "@auth/prisma-adapter": "^2.4.2",