├── README.md
├── .gitignore
├── api
├── .gitignore
├── src
│ ├── lib
│ │ ├── redis.js
│ │ └── utils.js
│ ├── routes
│ │ ├── dashboard
│ │ │ ├── index.js
│ │ │ └── @me
│ │ │ │ └── index.js
│ │ ├── base-router.js
│ │ ├── tickets
│ │ │ └── index.js
│ │ └── auth
│ │ │ └── index.js
│ ├── middlewares
│ │ ├── base-middleware.js
│ │ └── set-req-user.js
│ ├── models
│ │ ├── User.js
│ │ ├── Ticket.js
│ │ └── Guild.js
│ └── index.js
├── .env.example
├── package.json
└── package-lock.json
├── site
├── src
│ ├── env.d.ts
│ ├── pages
│ │ └── index.astro
│ └── layouts
│ │ └── Layout.astro
├── tsconfig.json
├── .vscode
│ ├── extensions.json
│ └── launch.json
├── astro.config.mjs
├── package.json
└── .gitignore
├── dashboard
├── src
│ ├── index.css
│ ├── lib
│ │ └── utils.js
│ ├── pages
│ │ └── index.jsx
│ ├── layouts
│ │ └── DefaultLayout.jsx
│ ├── main.jsx
│ └── components
│ │ ├── Footer.jsx
│ │ ├── GuildsList.jsx
│ │ └── Navbar.jsx
├── postcss.config.js
├── vite.config.js
├── .gitignore
├── tailwind.config.js
├── index.html
├── .eslintrc.cjs
├── package.json
└── public
│ └── vite.svg
└── bot
└── package.json
/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | TODO.md
2 | .DS_Store
3 | node_modules
--------------------------------------------------------------------------------
/api/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 | .DS_Store
--------------------------------------------------------------------------------
/site/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/site/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/base"
3 | }
4 |
--------------------------------------------------------------------------------
/dashboard/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/bot/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bot",
3 | "version": "1.0.0",
4 | "main": "src/index.js"
5 | }
6 |
--------------------------------------------------------------------------------
/api/src/lib/redis.js:
--------------------------------------------------------------------------------
1 | const { Redis } = require('ioredis');
2 |
3 | const redis = new Redis();
4 |
5 | module.exports = redis;
6 |
--------------------------------------------------------------------------------
/dashboard/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/site/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["astro-build.astro-vscode"],
3 | "unwantedRecommendations": []
4 | }
5 |
--------------------------------------------------------------------------------
/api/.env.example:
--------------------------------------------------------------------------------
1 | NODE_ENV=
2 |
3 | MONGODB_URI=
4 | DISCORD_CLIENT_ID=
5 | DISCORD_CLIENT_SECRET=
6 | DISCORD_REDIRECT_URI=
7 | JWT_SECRET=
--------------------------------------------------------------------------------
/site/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 |
3 | // https://astro.build/config
4 | export default defineConfig({});
5 |
--------------------------------------------------------------------------------
/dashboard/src/lib/utils.js:
--------------------------------------------------------------------------------
1 | import { clsx } from 'clsx';
2 | import { twMerge } from 'tailwind-merge';
3 |
4 | export function cn(...inputs) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
--------------------------------------------------------------------------------
/api/src/routes/dashboard/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 |
3 | const router = express.Router();
4 |
5 | router.use('/@me', require('./@me'));
6 |
7 | module.exports = router;
8 |
--------------------------------------------------------------------------------
/dashboard/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import react from '@vitejs/plugin-react';
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | });
8 |
--------------------------------------------------------------------------------
/api/src/middlewares/base-middleware.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const setReqUser = require('./set-req-user');
3 |
4 | const router = express.Router();
5 |
6 | router.use(setReqUser);
7 |
8 | module.exports = router;
9 |
--------------------------------------------------------------------------------
/site/src/pages/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Layout from '../layouts/Layout.astro';
3 | ---
4 |
5 |
6 |
7 |
Ticket Bot website
8 |
Coming soon...
9 |
10 |
11 |
--------------------------------------------------------------------------------
/site/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "command": "./node_modules/.bin/astro dev",
6 | "name": "Development server",
7 | "request": "launch",
8 | "type": "node-terminal"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/api/src/routes/base-router.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 |
3 | const router = express.Router();
4 |
5 | router.use('/auth', require('./auth'));
6 | router.use('/tickets', require('./tickets'));
7 | router.use('/dashboard', require('./dashboard'));
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/dashboard/src/pages/index.jsx:
--------------------------------------------------------------------------------
1 | import GuildsList from '../components/GuildsList';
2 | import DefaultLayout from '../layouts/DefaultLayout';
3 |
4 | function Index() {
5 | return (
6 |
7 |
8 |
9 | );
10 | }
11 |
12 | export default Index;
13 |
--------------------------------------------------------------------------------
/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "site",
3 | "type": "module",
4 | "version": "0.0.1",
5 | "scripts": {
6 | "dev": "astro dev",
7 | "start": "astro dev",
8 | "build": "astro build",
9 | "preview": "astro preview",
10 | "astro": "astro"
11 | },
12 | "dependencies": {
13 | "astro": "^4.9.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/dashboard/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "1.0.0",
4 | "main": "src/index.js",
5 | "dependencies": {
6 | "cookie-parser": "^1.4.6",
7 | "cors": "^2.8.5",
8 | "discord.js": "^14.15.3",
9 | "dotenv": "^16.4.5",
10 | "express": "^4.19.2",
11 | "ioredis": "^5.4.1",
12 | "jsonwebtoken": "^9.0.2",
13 | "mongoose": "^8.4.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/site/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 |
4 | # generated types
5 | .astro/
6 |
7 | # dependencies
8 | node_modules/
9 |
10 | # logs
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # environment variables
17 | .env
18 | .env.production
19 |
20 | # macOS-specific files
21 | .DS_Store
22 |
23 | # jetbrains setting folder
24 | .idea/
25 |
--------------------------------------------------------------------------------
/api/src/lib/utils.js:
--------------------------------------------------------------------------------
1 | const { PermissionsBitField } = require('discord.js');
2 |
3 | /**
4 | * @param {string | number | bigint} permissions
5 | * @param {import('discord.js').PermissionsString} permission
6 | */
7 | function hasPermissions(permissions, permission) {
8 | const perms = new PermissionsBitField(permissions);
9 | return perms.has(permission);
10 | }
11 |
12 | module.exports = { hasPermissions };
13 |
--------------------------------------------------------------------------------
/dashboard/src/layouts/DefaultLayout.jsx:
--------------------------------------------------------------------------------
1 | import Footer from '../components/Footer';
2 | import Navbar from '../components/Navbar';
3 |
4 | export default function DefaultLayout({ children }) {
5 | return (
6 |
7 |
8 | {children}
9 |
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/dashboard/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
4 | theme: {
5 | extend: {
6 | container: {
7 | padding: '1rem',
8 | center: true,
9 | },
10 | },
11 | },
12 | plugins: [require('daisyui')],
13 | daisyui: {
14 | themes: ['dracula'],
15 | logs: false,
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/dashboard/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dashboard - Tick-it
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/api/src/models/User.js:
--------------------------------------------------------------------------------
1 | const { Schema, model } = require('mongoose');
2 |
3 | const userSchema = new Schema(
4 | {
5 | id: { type: String, required: true },
6 | username: { type: String, required: true },
7 | avatarHash: { type: String, default: null },
8 | accessToken: { type: String, required: true },
9 | refreshToken: { type: String, required: true },
10 | },
11 | { timestamps: true }
12 | );
13 |
14 | module.exports = model('User', userSchema);
15 |
--------------------------------------------------------------------------------
/dashboard/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createRoot } from 'react-dom/client';
3 | import { createBrowserRouter, RouterProvider } from 'react-router-dom';
4 | import './index.css';
5 |
6 | // Pages
7 | import Index from './pages/index';
8 |
9 | const router = createBrowserRouter([
10 | { path: '/', element: },
11 | // ...
12 | ]);
13 |
14 | createRoot(document.getElementById('root')).render(
15 |
16 |
17 |
18 | );
19 |
--------------------------------------------------------------------------------
/site/src/layouts/Layout.astro:
--------------------------------------------------------------------------------
1 | ---
2 | interface Props {
3 | title: string;
4 | }
5 |
6 | const { title } = Astro.props;
7 | ---
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | {title}
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/api/src/routes/tickets/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 |
3 | const router = express.Router();
4 |
5 | router.get('/guilds', (req, res) => {
6 | console.log(req.user);
7 | res.send('received!');
8 | });
9 |
10 | // GET: api.tick-it.com/tickets/guild/19873489234
11 |
12 | router.get('/guild/:id', (req, res) => {
13 | const { id: guildId } = req.params;
14 |
15 | res.send(`Getting tickets for guild id ${guildId}`);
16 | });
17 |
18 | router.post('/', (req, res) => {
19 | res.send('POST: tickets route');
20 | });
21 |
22 | module.exports = router;
23 |
--------------------------------------------------------------------------------
/api/src/middlewares/set-req-user.js:
--------------------------------------------------------------------------------
1 | const User = require('../models/User');
2 | const jwt = require('jsonwebtoken');
3 |
4 | module.exports = async (req, res, next) => {
5 | try {
6 | const cookies = req.cookies;
7 | const token = cookies?.token;
8 |
9 | if (!token) return next();
10 |
11 | const decodedToken = jwt.verify(token, process.env.JWT_SECRET);
12 |
13 | if (decodedToken?.id) {
14 | const targetUser = await User.findOne({ id: decodedToken.id }).lean();
15 |
16 | if (targetUser) req.user = targetUser;
17 | }
18 | } catch (error) {
19 | console.error(error);
20 | }
21 |
22 | next();
23 | };
24 |
--------------------------------------------------------------------------------
/dashboard/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react/jsx-no-target-blank': 'off',
16 | 'react-refresh/only-export-components': [
17 | 'warn',
18 | { allowConstantExport: true },
19 | ],
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/dashboard/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | export default function Footer() {
2 | return (
3 |
4 |
© 2024 All Rights Reserved.
5 |
6 |
24 |
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/api/src/models/Ticket.js:
--------------------------------------------------------------------------------
1 | const { Schema, model } = require('mongoose');
2 | const { randomUUID } = require('node:crypto');
3 |
4 | const ticketSchema = new Schema(
5 | {
6 | id: {
7 | type: String,
8 | default: randomUUID,
9 | },
10 | guildId: {
11 | type: String,
12 | required: true,
13 | },
14 | ownerId: {
15 | type: String,
16 | required: true,
17 | },
18 | reason: {
19 | type: String,
20 | default: null,
21 | },
22 | claimerId: {
23 | type: String,
24 | default: null,
25 | },
26 | status: {
27 | type: String,
28 | enum: ['OPEN', 'CLOSED', 'DELETED'],
29 | default: 'OPEN',
30 | },
31 | },
32 | { timestamps: true }
33 | );
34 |
35 | module.exports = model('Ticket', ticketSchema);
36 |
--------------------------------------------------------------------------------
/api/src/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const mongoose = require('mongoose');
3 | const baseRouter = require('./routes/base-router');
4 | const baseMiddleware = require('./middlewares/base-middleware');
5 | const cookieParser = require('cookie-parser');
6 | const cors = require('cors');
7 | require('dotenv/config');
8 |
9 | const app = express();
10 |
11 | app.use(cors({ credentials: true, origin: 'http://localhost:5173' }));
12 | app.use(cookieParser());
13 | app.use('/', baseMiddleware);
14 | app.use('/', baseRouter);
15 |
16 | const PORT = 3001;
17 |
18 | if (!process.env.MONGODB_URI) {
19 | throw new Error('MONGODB_URI required in .env');
20 | }
21 |
22 | mongoose.connect(process.env.MONGODB_URI).then(() => {
23 | console.log('Connected to database.');
24 |
25 | app.listen(PORT, () => {
26 | console.log(`Listening on port ${PORT}`);
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/api/src/models/Guild.js:
--------------------------------------------------------------------------------
1 | const { Schema, model } = require('mongoose');
2 |
3 | const guildSchema = new Schema(
4 | {
5 | id: {
6 | type: String,
7 | required: true,
8 | },
9 | name: {
10 | type: String,
11 | required: true,
12 | },
13 | iconHash: {
14 | type: String,
15 | default: null,
16 | },
17 | openTicketsCategoryId: {
18 | type: String,
19 | default: null,
20 | },
21 | closedTicketsCategoryId: {
22 | type: String,
23 | default: null,
24 | },
25 | transcriptsChannelId: {
26 | type: String,
27 | default: null,
28 | },
29 | modRoleIds: {
30 | type: [String],
31 | default: [],
32 | },
33 | pingRoleIds: {
34 | type: [String],
35 | default: [],
36 | },
37 | },
38 | { timestamps: true }
39 | );
40 |
41 | module.exports = model('Guild', guildSchema);
42 |
--------------------------------------------------------------------------------
/dashboard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dashboard",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "clsx": "^2.1.1",
14 | "lucide-react": "^0.390.0",
15 | "react": "^18.2.0",
16 | "react-dom": "^18.2.0",
17 | "react-icons": "^5.2.1",
18 | "react-router-dom": "^6.23.1",
19 | "tailwind-merge": "^2.3.0"
20 | },
21 | "devDependencies": {
22 | "@types/react": "^18.2.66",
23 | "@types/react-dom": "^18.2.22",
24 | "@vitejs/plugin-react": "^4.2.1",
25 | "autoprefixer": "^10.4.19",
26 | "daisyui": "^4.11.1",
27 | "eslint": "^8.57.0",
28 | "eslint-plugin-react": "^7.34.1",
29 | "eslint-plugin-react-hooks": "^4.6.0",
30 | "eslint-plugin-react-refresh": "^0.4.6",
31 | "postcss": "^8.4.38",
32 | "tailwindcss": "^3.4.3",
33 | "vite": "^5.2.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/dashboard/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/api/src/routes/dashboard/@me/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const { hasPermissions } = require('../../../lib/utils');
3 | const redis = require('../../../lib/redis');
4 |
5 | const router = express.Router();
6 |
7 | const DISCORD_ENDPOINT = 'https://discord.com/api/v10';
8 |
9 | router.get('/', (req, res) => {
10 | if (req.user) {
11 | const { accessToken, refreshToken, ...user } = req.user;
12 |
13 | res.status(200).json(user);
14 | } else {
15 | res.status(401).json({ message: 'Not logged in' });
16 | }
17 | });
18 |
19 | router.get('/guilds', async (req, res) => {
20 | if (!req.user?.accessToken) {
21 | return res.status(401).json({ message: 'Not logged in' });
22 | }
23 |
24 | const skipCache = req.query.skipcache;
25 |
26 | if (!skipCache) {
27 | const redisCacheRes = await redis.get(`user-guilds:${req.user.id}`);
28 |
29 | if (redisCacheRes) {
30 | return res.status(200).json(JSON.parse(redisCacheRes));
31 | }
32 | }
33 |
34 | const guildsRes = await fetch(`${DISCORD_ENDPOINT}/users/@me/guilds`, {
35 | headers: {
36 | Authorization: `Bearer ${req.user.accessToken}`,
37 | },
38 | });
39 |
40 | if (!guildsRes.ok) {
41 | return res.status(500).json({ message: 'Failed to fetch guilds' });
42 | }
43 |
44 | const guilds = await guildsRes.json();
45 |
46 | const filteredGuilds = guilds.filter((guild) =>
47 | hasPermissions(guild.permissions, 'ManageGuild')
48 | );
49 |
50 | await redis.set(
51 | `user-guilds:${req.user.id}`,
52 | JSON.stringify(filteredGuilds),
53 | 'EX',
54 | 600
55 | );
56 |
57 | res.status(200).json(filteredGuilds);
58 | });
59 |
60 | module.exports = router;
61 |
--------------------------------------------------------------------------------
/api/src/routes/auth/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const User = require('../../models/User');
3 | const jwt = require('jsonwebtoken');
4 |
5 | const router = express.Router();
6 |
7 | // GET: api.tick-it.com/auth/signin
8 | // GET: api.tick-it.com/auth/callback
9 |
10 | const DASHBOARD_URL = 'http://localhost:5173';
11 |
12 | router.get('/signin', (req, res) => {
13 | res.redirect(
14 | `https://discord.com/oauth2/authorize?client_id=${process.env.DISCORD_CLIENT_ID}&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3001%2Fauth%2Fcallback&scope=guilds+identify`
15 | );
16 | });
17 |
18 | router.get('/callback', async (req, res) => {
19 | const DISCORD_ENDPOINT = 'https://discord.com/api/v10';
20 | const CLIENT_ID = process.env.DISCORD_CLIENT_ID;
21 | const CLIENT_SECRET = process.env.DISCORD_CLIENT_SECRET;
22 | const REDIRECT_URI = process.env.DISCORD_REDIRECT_URI;
23 |
24 | const { code } = req.query;
25 |
26 | if (!code) {
27 | return res.status(400).json({
28 | error: 'A "code" query parameter must be present in the URL.',
29 | });
30 | }
31 |
32 | const oauthRes = await fetch(`${DISCORD_ENDPOINT}/oauth2/token`, {
33 | method: 'POST',
34 | body: new URLSearchParams({
35 | client_id: CLIENT_ID,
36 | client_secret: CLIENT_SECRET,
37 | grant_type: 'authorization_code',
38 | redirect_uri: REDIRECT_URI,
39 | code,
40 | }).toString(),
41 | headers: {
42 | 'Content-Type': 'application/x-www-form-urlencoded',
43 | },
44 | });
45 |
46 | if (!oauthRes.ok) {
47 | console.log('error', oauthRes);
48 | res.send('error');
49 | return;
50 | }
51 |
52 | const oauthResJson = await oauthRes.json();
53 |
54 | const userRes = await fetch(`${DISCORD_ENDPOINT}/users/@me`, {
55 | method: 'GET',
56 | headers: {
57 | 'Content-Type': 'application/x-www-form-urlencoded',
58 | Authorization: `Bearer ${oauthResJson.access_token}`,
59 | },
60 | });
61 |
62 | if (!userRes.ok) {
63 | return res.send('error');
64 | }
65 |
66 | const userResJson = await userRes.json();
67 |
68 | let user = await User.findOne({ id: userResJson.id });
69 |
70 | if (!user) {
71 | user = new User({
72 | id: userResJson.id,
73 | username: userResJson.username,
74 | avatarHash: userResJson.avatar,
75 | accessToken: oauthResJson.access_token,
76 | refreshToken: oauthResJson.refresh_token,
77 | });
78 | } else {
79 | user.username = userResJson.username;
80 | user.avatarHash = userResJson.avatar;
81 | user.accessToken = oauthResJson.access_token;
82 | user.refreshToken = oauthResJson.refresh_token;
83 | }
84 |
85 | await user.save();
86 |
87 | const token = jwt.sign(
88 | {
89 | id: userResJson.id,
90 | username: userResJson.username,
91 | avatarHash: userResJson.avatar,
92 | },
93 | process.env.JWT_SECRET,
94 | { expiresIn: '7d' }
95 | );
96 |
97 | res
98 | .status(200)
99 | .cookie('token', token, {
100 | domain: 'localhost',
101 | httpOnly: true,
102 | // expires: new Date(Date.now() + 6.048e8),
103 | secure: process.env.NODE_ENV === 'development',
104 | maxAge: 6.048e8,
105 | // sameSite: ''
106 | })
107 | .redirect(DASHBOARD_URL);
108 | });
109 |
110 | router.get('/signout', (req, res) => {
111 | res.clearCookie('token').sendStatus(200);
112 | });
113 |
114 | module.exports = router;
115 |
--------------------------------------------------------------------------------
/dashboard/src/components/GuildsList.jsx:
--------------------------------------------------------------------------------
1 | import { Loader2, RefreshCcw } from 'lucide-react';
2 | import { useEffect, useState } from 'react';
3 | import { FaDiscord } from 'react-icons/fa';
4 | import { Link } from 'react-router-dom';
5 | import { cn } from '../lib/utils';
6 |
7 | const SIGNIN_URL = 'http://localhost:3001/auth/signin';
8 |
9 | export default function GuildsList() {
10 | const [guilds, setGuilds] = useState([]);
11 | const [loading, setLoading] = useState(true);
12 |
13 | useEffect(() => {
14 | (async () => {
15 | setLoading(true);
16 |
17 | try {
18 | const res = await fetch('http://localhost:3001/dashboard/@me/guilds', {
19 | credentials: 'include',
20 | });
21 |
22 | if (!res.ok) {
23 | switch (res.status) {
24 | case 401:
25 | window.location.href = SIGNIN_URL;
26 | throw new Error('Not authenticated');
27 |
28 | default:
29 | throw new Error('An error occurred');
30 | }
31 | }
32 |
33 | const guilds = await res.json();
34 |
35 | setGuilds(guilds);
36 | } catch (error) {
37 | console.log(error);
38 | }
39 |
40 | setLoading(false);
41 | })();
42 | }, []);
43 |
44 | async function handleRefresh() {
45 | setLoading(true);
46 |
47 | try {
48 | const res = await fetch(
49 | 'http://localhost:3001/dashboard/@me/guilds?skipcache=true',
50 | { credentials: 'include' }
51 | );
52 |
53 | if (!res.ok) {
54 | throw new Error('An error occurred');
55 | }
56 |
57 | const guilds = await res.json();
58 |
59 | setGuilds(guilds);
60 | } catch (error) {
61 | console.log(error);
62 | }
63 |
64 | setLoading(false);
65 | }
66 |
67 | return (
68 |
69 |
77 |
78 |
79 | {loading ? (
80 |
81 |
82 |
83 | ) : (
84 | <>
85 | {!guilds.length ? (
86 |
No servers found
87 | ) : (
88 | <>
89 | {guilds.map((guild) => (
90 |
94 | {guild.icon ? (
95 | <>
96 |

102 |

107 | >
108 | ) : (
109 | <>
110 |
111 |
112 |
113 |
114 | >
115 | )}
116 |
117 | {guild.name}
118 |
119 |
120 |
124 | Configure
125 |
126 |
127 | ))}
128 | >
129 | )}
130 | >
131 | )}
132 |
133 |
134 | );
135 | }
136 |
--------------------------------------------------------------------------------
/dashboard/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import { CircleUser, Loader2, LogOut } from 'lucide-react';
2 | import { useEffect, useState } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | export default function Navbar() {
6 | const [user, setUser] = useState(null);
7 | const [loading, setLoading] = useState(true);
8 |
9 | useEffect(() => {
10 | (async () => {
11 | setLoading(true);
12 |
13 | try {
14 | const res = await fetch('http://localhost:3001/dashboard/@me', {
15 | credentials: 'include',
16 | });
17 |
18 | if (!res.ok) {
19 | throw new Error('Not authenticated');
20 | }
21 |
22 | const user = await res.json();
23 |
24 | setUser(user);
25 | } catch (error) {
26 | console.log(error);
27 | }
28 |
29 | setLoading(false);
30 | })();
31 | }, []);
32 |
33 | async function handleLogout() {
34 | try {
35 | const res = await fetch('http://localhost:3001/auth/signout', {
36 | credentials: 'include',
37 | });
38 |
39 | if (!res.ok) {
40 | throw new Error('Failed to logout');
41 | }
42 |
43 | window.location.href = '/';
44 | } catch (error) {
45 | console.log(error);
46 | }
47 | }
48 |
49 | return (
50 | <>
51 |
154 | >
155 | );
156 | }
157 |
--------------------------------------------------------------------------------
/api/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "api",
9 | "version": "1.0.0",
10 | "dependencies": {
11 | "cookie-parser": "^1.4.6",
12 | "cors": "^2.8.5",
13 | "discord.js": "^14.15.3",
14 | "dotenv": "^16.4.5",
15 | "express": "^4.19.2",
16 | "ioredis": "^5.4.1",
17 | "jsonwebtoken": "^9.0.2",
18 | "mongoose": "^8.4.0"
19 | }
20 | },
21 | "node_modules/@discordjs/builders": {
22 | "version": "1.8.2",
23 | "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.8.2.tgz",
24 | "integrity": "sha512-6wvG3QaCjtMu0xnle4SoOIeFB4y6fKMN6WZfy3BMKJdQQtPLik8KGzDwBVL/+wTtcE/ZlFjgEk74GublyEVZ7g==",
25 | "dependencies": {
26 | "@discordjs/formatters": "^0.4.0",
27 | "@discordjs/util": "^1.1.0",
28 | "@sapphire/shapeshift": "^3.9.7",
29 | "discord-api-types": "0.37.83",
30 | "fast-deep-equal": "^3.1.3",
31 | "ts-mixer": "^6.0.4",
32 | "tslib": "^2.6.2"
33 | },
34 | "engines": {
35 | "node": ">=16.11.0"
36 | },
37 | "funding": {
38 | "url": "https://github.com/discordjs/discord.js?sponsor"
39 | }
40 | },
41 | "node_modules/@discordjs/collection": {
42 | "version": "1.5.3",
43 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
44 | "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
45 | "engines": {
46 | "node": ">=16.11.0"
47 | }
48 | },
49 | "node_modules/@discordjs/formatters": {
50 | "version": "0.4.0",
51 | "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.4.0.tgz",
52 | "integrity": "sha512-fJ06TLC1NiruF35470q3Nr1bi95BdvKFAF+T5bNfZJ4bNdqZ3VZ+Ttg6SThqTxm6qumSG3choxLBHMC69WXNXQ==",
53 | "dependencies": {
54 | "discord-api-types": "0.37.83"
55 | },
56 | "engines": {
57 | "node": ">=16.11.0"
58 | },
59 | "funding": {
60 | "url": "https://github.com/discordjs/discord.js?sponsor"
61 | }
62 | },
63 | "node_modules/@discordjs/rest": {
64 | "version": "2.3.0",
65 | "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.3.0.tgz",
66 | "integrity": "sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg==",
67 | "dependencies": {
68 | "@discordjs/collection": "^2.1.0",
69 | "@discordjs/util": "^1.1.0",
70 | "@sapphire/async-queue": "^1.5.2",
71 | "@sapphire/snowflake": "^3.5.3",
72 | "@vladfrangu/async_event_emitter": "^2.2.4",
73 | "discord-api-types": "0.37.83",
74 | "magic-bytes.js": "^1.10.0",
75 | "tslib": "^2.6.2",
76 | "undici": "6.13.0"
77 | },
78 | "engines": {
79 | "node": ">=16.11.0"
80 | },
81 | "funding": {
82 | "url": "https://github.com/discordjs/discord.js?sponsor"
83 | }
84 | },
85 | "node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
86 | "version": "2.1.0",
87 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.0.tgz",
88 | "integrity": "sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==",
89 | "engines": {
90 | "node": ">=18"
91 | },
92 | "funding": {
93 | "url": "https://github.com/discordjs/discord.js?sponsor"
94 | }
95 | },
96 | "node_modules/@discordjs/util": {
97 | "version": "1.1.0",
98 | "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.0.tgz",
99 | "integrity": "sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg==",
100 | "engines": {
101 | "node": ">=16.11.0"
102 | },
103 | "funding": {
104 | "url": "https://github.com/discordjs/discord.js?sponsor"
105 | }
106 | },
107 | "node_modules/@discordjs/ws": {
108 | "version": "1.1.1",
109 | "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.1.1.tgz",
110 | "integrity": "sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==",
111 | "dependencies": {
112 | "@discordjs/collection": "^2.1.0",
113 | "@discordjs/rest": "^2.3.0",
114 | "@discordjs/util": "^1.1.0",
115 | "@sapphire/async-queue": "^1.5.2",
116 | "@types/ws": "^8.5.10",
117 | "@vladfrangu/async_event_emitter": "^2.2.4",
118 | "discord-api-types": "0.37.83",
119 | "tslib": "^2.6.2",
120 | "ws": "^8.16.0"
121 | },
122 | "engines": {
123 | "node": ">=16.11.0"
124 | },
125 | "funding": {
126 | "url": "https://github.com/discordjs/discord.js?sponsor"
127 | }
128 | },
129 | "node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
130 | "version": "2.1.0",
131 | "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.0.tgz",
132 | "integrity": "sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==",
133 | "engines": {
134 | "node": ">=18"
135 | },
136 | "funding": {
137 | "url": "https://github.com/discordjs/discord.js?sponsor"
138 | }
139 | },
140 | "node_modules/@ioredis/commands": {
141 | "version": "1.2.0",
142 | "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
143 | "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="
144 | },
145 | "node_modules/@mongodb-js/saslprep": {
146 | "version": "1.1.7",
147 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz",
148 | "integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==",
149 | "dependencies": {
150 | "sparse-bitfield": "^3.0.3"
151 | }
152 | },
153 | "node_modules/@sapphire/async-queue": {
154 | "version": "1.5.2",
155 | "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.2.tgz",
156 | "integrity": "sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==",
157 | "engines": {
158 | "node": ">=v14.0.0",
159 | "npm": ">=7.0.0"
160 | }
161 | },
162 | "node_modules/@sapphire/shapeshift": {
163 | "version": "3.9.7",
164 | "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz",
165 | "integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==",
166 | "dependencies": {
167 | "fast-deep-equal": "^3.1.3",
168 | "lodash": "^4.17.21"
169 | },
170 | "engines": {
171 | "node": ">=v16"
172 | }
173 | },
174 | "node_modules/@sapphire/snowflake": {
175 | "version": "3.5.3",
176 | "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz",
177 | "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==",
178 | "engines": {
179 | "node": ">=v14.0.0",
180 | "npm": ">=7.0.0"
181 | }
182 | },
183 | "node_modules/@types/node": {
184 | "version": "20.14.2",
185 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
186 | "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
187 | "dependencies": {
188 | "undici-types": "~5.26.4"
189 | }
190 | },
191 | "node_modules/@types/webidl-conversions": {
192 | "version": "7.0.3",
193 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
194 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="
195 | },
196 | "node_modules/@types/whatwg-url": {
197 | "version": "11.0.5",
198 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
199 | "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
200 | "dependencies": {
201 | "@types/webidl-conversions": "*"
202 | }
203 | },
204 | "node_modules/@types/ws": {
205 | "version": "8.5.10",
206 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
207 | "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
208 | "dependencies": {
209 | "@types/node": "*"
210 | }
211 | },
212 | "node_modules/@vladfrangu/async_event_emitter": {
213 | "version": "2.2.4",
214 | "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz",
215 | "integrity": "sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==",
216 | "engines": {
217 | "node": ">=v14.0.0",
218 | "npm": ">=7.0.0"
219 | }
220 | },
221 | "node_modules/accepts": {
222 | "version": "1.3.8",
223 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
224 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
225 | "dependencies": {
226 | "mime-types": "~2.1.34",
227 | "negotiator": "0.6.3"
228 | },
229 | "engines": {
230 | "node": ">= 0.6"
231 | }
232 | },
233 | "node_modules/array-flatten": {
234 | "version": "1.1.1",
235 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
236 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
237 | },
238 | "node_modules/body-parser": {
239 | "version": "1.20.2",
240 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
241 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
242 | "dependencies": {
243 | "bytes": "3.1.2",
244 | "content-type": "~1.0.5",
245 | "debug": "2.6.9",
246 | "depd": "2.0.0",
247 | "destroy": "1.2.0",
248 | "http-errors": "2.0.0",
249 | "iconv-lite": "0.4.24",
250 | "on-finished": "2.4.1",
251 | "qs": "6.11.0",
252 | "raw-body": "2.5.2",
253 | "type-is": "~1.6.18",
254 | "unpipe": "1.0.0"
255 | },
256 | "engines": {
257 | "node": ">= 0.8",
258 | "npm": "1.2.8000 || >= 1.4.16"
259 | }
260 | },
261 | "node_modules/bson": {
262 | "version": "6.7.0",
263 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz",
264 | "integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==",
265 | "engines": {
266 | "node": ">=16.20.1"
267 | }
268 | },
269 | "node_modules/buffer-equal-constant-time": {
270 | "version": "1.0.1",
271 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
272 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
273 | },
274 | "node_modules/bytes": {
275 | "version": "3.1.2",
276 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
277 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
278 | "engines": {
279 | "node": ">= 0.8"
280 | }
281 | },
282 | "node_modules/call-bind": {
283 | "version": "1.0.7",
284 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
285 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
286 | "dependencies": {
287 | "es-define-property": "^1.0.0",
288 | "es-errors": "^1.3.0",
289 | "function-bind": "^1.1.2",
290 | "get-intrinsic": "^1.2.4",
291 | "set-function-length": "^1.2.1"
292 | },
293 | "engines": {
294 | "node": ">= 0.4"
295 | },
296 | "funding": {
297 | "url": "https://github.com/sponsors/ljharb"
298 | }
299 | },
300 | "node_modules/cluster-key-slot": {
301 | "version": "1.1.2",
302 | "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
303 | "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
304 | "engines": {
305 | "node": ">=0.10.0"
306 | }
307 | },
308 | "node_modules/content-disposition": {
309 | "version": "0.5.4",
310 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
311 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
312 | "dependencies": {
313 | "safe-buffer": "5.2.1"
314 | },
315 | "engines": {
316 | "node": ">= 0.6"
317 | }
318 | },
319 | "node_modules/content-type": {
320 | "version": "1.0.5",
321 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
322 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
323 | "engines": {
324 | "node": ">= 0.6"
325 | }
326 | },
327 | "node_modules/cookie": {
328 | "version": "0.6.0",
329 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
330 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
331 | "engines": {
332 | "node": ">= 0.6"
333 | }
334 | },
335 | "node_modules/cookie-parser": {
336 | "version": "1.4.6",
337 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
338 | "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
339 | "dependencies": {
340 | "cookie": "0.4.1",
341 | "cookie-signature": "1.0.6"
342 | },
343 | "engines": {
344 | "node": ">= 0.8.0"
345 | }
346 | },
347 | "node_modules/cookie-parser/node_modules/cookie": {
348 | "version": "0.4.1",
349 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
350 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
351 | "engines": {
352 | "node": ">= 0.6"
353 | }
354 | },
355 | "node_modules/cookie-signature": {
356 | "version": "1.0.6",
357 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
358 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
359 | },
360 | "node_modules/cors": {
361 | "version": "2.8.5",
362 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
363 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
364 | "dependencies": {
365 | "object-assign": "^4",
366 | "vary": "^1"
367 | },
368 | "engines": {
369 | "node": ">= 0.10"
370 | }
371 | },
372 | "node_modules/debug": {
373 | "version": "2.6.9",
374 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
375 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
376 | "dependencies": {
377 | "ms": "2.0.0"
378 | }
379 | },
380 | "node_modules/define-data-property": {
381 | "version": "1.1.4",
382 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
383 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
384 | "dependencies": {
385 | "es-define-property": "^1.0.0",
386 | "es-errors": "^1.3.0",
387 | "gopd": "^1.0.1"
388 | },
389 | "engines": {
390 | "node": ">= 0.4"
391 | },
392 | "funding": {
393 | "url": "https://github.com/sponsors/ljharb"
394 | }
395 | },
396 | "node_modules/denque": {
397 | "version": "2.1.0",
398 | "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
399 | "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
400 | "engines": {
401 | "node": ">=0.10"
402 | }
403 | },
404 | "node_modules/depd": {
405 | "version": "2.0.0",
406 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
407 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
408 | "engines": {
409 | "node": ">= 0.8"
410 | }
411 | },
412 | "node_modules/destroy": {
413 | "version": "1.2.0",
414 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
415 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
416 | "engines": {
417 | "node": ">= 0.8",
418 | "npm": "1.2.8000 || >= 1.4.16"
419 | }
420 | },
421 | "node_modules/discord-api-types": {
422 | "version": "0.37.83",
423 | "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.83.tgz",
424 | "integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA=="
425 | },
426 | "node_modules/discord.js": {
427 | "version": "14.15.3",
428 | "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.15.3.tgz",
429 | "integrity": "sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ==",
430 | "dependencies": {
431 | "@discordjs/builders": "^1.8.2",
432 | "@discordjs/collection": "1.5.3",
433 | "@discordjs/formatters": "^0.4.0",
434 | "@discordjs/rest": "^2.3.0",
435 | "@discordjs/util": "^1.1.0",
436 | "@discordjs/ws": "^1.1.1",
437 | "@sapphire/snowflake": "3.5.3",
438 | "discord-api-types": "0.37.83",
439 | "fast-deep-equal": "3.1.3",
440 | "lodash.snakecase": "4.1.1",
441 | "tslib": "2.6.2",
442 | "undici": "6.13.0"
443 | },
444 | "engines": {
445 | "node": ">=16.11.0"
446 | },
447 | "funding": {
448 | "url": "https://github.com/discordjs/discord.js?sponsor"
449 | }
450 | },
451 | "node_modules/dotenv": {
452 | "version": "16.4.5",
453 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
454 | "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
455 | "engines": {
456 | "node": ">=12"
457 | },
458 | "funding": {
459 | "url": "https://dotenvx.com"
460 | }
461 | },
462 | "node_modules/ecdsa-sig-formatter": {
463 | "version": "1.0.11",
464 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
465 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
466 | "dependencies": {
467 | "safe-buffer": "^5.0.1"
468 | }
469 | },
470 | "node_modules/ee-first": {
471 | "version": "1.1.1",
472 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
473 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
474 | },
475 | "node_modules/encodeurl": {
476 | "version": "1.0.2",
477 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
478 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
479 | "engines": {
480 | "node": ">= 0.8"
481 | }
482 | },
483 | "node_modules/es-define-property": {
484 | "version": "1.0.0",
485 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
486 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
487 | "dependencies": {
488 | "get-intrinsic": "^1.2.4"
489 | },
490 | "engines": {
491 | "node": ">= 0.4"
492 | }
493 | },
494 | "node_modules/es-errors": {
495 | "version": "1.3.0",
496 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
497 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
498 | "engines": {
499 | "node": ">= 0.4"
500 | }
501 | },
502 | "node_modules/escape-html": {
503 | "version": "1.0.3",
504 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
505 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
506 | },
507 | "node_modules/etag": {
508 | "version": "1.8.1",
509 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
510 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
511 | "engines": {
512 | "node": ">= 0.6"
513 | }
514 | },
515 | "node_modules/express": {
516 | "version": "4.19.2",
517 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
518 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
519 | "dependencies": {
520 | "accepts": "~1.3.8",
521 | "array-flatten": "1.1.1",
522 | "body-parser": "1.20.2",
523 | "content-disposition": "0.5.4",
524 | "content-type": "~1.0.4",
525 | "cookie": "0.6.0",
526 | "cookie-signature": "1.0.6",
527 | "debug": "2.6.9",
528 | "depd": "2.0.0",
529 | "encodeurl": "~1.0.2",
530 | "escape-html": "~1.0.3",
531 | "etag": "~1.8.1",
532 | "finalhandler": "1.2.0",
533 | "fresh": "0.5.2",
534 | "http-errors": "2.0.0",
535 | "merge-descriptors": "1.0.1",
536 | "methods": "~1.1.2",
537 | "on-finished": "2.4.1",
538 | "parseurl": "~1.3.3",
539 | "path-to-regexp": "0.1.7",
540 | "proxy-addr": "~2.0.7",
541 | "qs": "6.11.0",
542 | "range-parser": "~1.2.1",
543 | "safe-buffer": "5.2.1",
544 | "send": "0.18.0",
545 | "serve-static": "1.15.0",
546 | "setprototypeof": "1.2.0",
547 | "statuses": "2.0.1",
548 | "type-is": "~1.6.18",
549 | "utils-merge": "1.0.1",
550 | "vary": "~1.1.2"
551 | },
552 | "engines": {
553 | "node": ">= 0.10.0"
554 | }
555 | },
556 | "node_modules/fast-deep-equal": {
557 | "version": "3.1.3",
558 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
559 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
560 | },
561 | "node_modules/finalhandler": {
562 | "version": "1.2.0",
563 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
564 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
565 | "dependencies": {
566 | "debug": "2.6.9",
567 | "encodeurl": "~1.0.2",
568 | "escape-html": "~1.0.3",
569 | "on-finished": "2.4.1",
570 | "parseurl": "~1.3.3",
571 | "statuses": "2.0.1",
572 | "unpipe": "~1.0.0"
573 | },
574 | "engines": {
575 | "node": ">= 0.8"
576 | }
577 | },
578 | "node_modules/forwarded": {
579 | "version": "0.2.0",
580 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
581 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
582 | "engines": {
583 | "node": ">= 0.6"
584 | }
585 | },
586 | "node_modules/fresh": {
587 | "version": "0.5.2",
588 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
589 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
590 | "engines": {
591 | "node": ">= 0.6"
592 | }
593 | },
594 | "node_modules/function-bind": {
595 | "version": "1.1.2",
596 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
597 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
598 | "funding": {
599 | "url": "https://github.com/sponsors/ljharb"
600 | }
601 | },
602 | "node_modules/get-intrinsic": {
603 | "version": "1.2.4",
604 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
605 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
606 | "dependencies": {
607 | "es-errors": "^1.3.0",
608 | "function-bind": "^1.1.2",
609 | "has-proto": "^1.0.1",
610 | "has-symbols": "^1.0.3",
611 | "hasown": "^2.0.0"
612 | },
613 | "engines": {
614 | "node": ">= 0.4"
615 | },
616 | "funding": {
617 | "url": "https://github.com/sponsors/ljharb"
618 | }
619 | },
620 | "node_modules/gopd": {
621 | "version": "1.0.1",
622 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
623 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
624 | "dependencies": {
625 | "get-intrinsic": "^1.1.3"
626 | },
627 | "funding": {
628 | "url": "https://github.com/sponsors/ljharb"
629 | }
630 | },
631 | "node_modules/has-property-descriptors": {
632 | "version": "1.0.2",
633 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
634 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
635 | "dependencies": {
636 | "es-define-property": "^1.0.0"
637 | },
638 | "funding": {
639 | "url": "https://github.com/sponsors/ljharb"
640 | }
641 | },
642 | "node_modules/has-proto": {
643 | "version": "1.0.3",
644 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
645 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
646 | "engines": {
647 | "node": ">= 0.4"
648 | },
649 | "funding": {
650 | "url": "https://github.com/sponsors/ljharb"
651 | }
652 | },
653 | "node_modules/has-symbols": {
654 | "version": "1.0.3",
655 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
656 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
657 | "engines": {
658 | "node": ">= 0.4"
659 | },
660 | "funding": {
661 | "url": "https://github.com/sponsors/ljharb"
662 | }
663 | },
664 | "node_modules/hasown": {
665 | "version": "2.0.2",
666 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
667 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
668 | "dependencies": {
669 | "function-bind": "^1.1.2"
670 | },
671 | "engines": {
672 | "node": ">= 0.4"
673 | }
674 | },
675 | "node_modules/http-errors": {
676 | "version": "2.0.0",
677 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
678 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
679 | "dependencies": {
680 | "depd": "2.0.0",
681 | "inherits": "2.0.4",
682 | "setprototypeof": "1.2.0",
683 | "statuses": "2.0.1",
684 | "toidentifier": "1.0.1"
685 | },
686 | "engines": {
687 | "node": ">= 0.8"
688 | }
689 | },
690 | "node_modules/iconv-lite": {
691 | "version": "0.4.24",
692 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
693 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
694 | "dependencies": {
695 | "safer-buffer": ">= 2.1.2 < 3"
696 | },
697 | "engines": {
698 | "node": ">=0.10.0"
699 | }
700 | },
701 | "node_modules/inherits": {
702 | "version": "2.0.4",
703 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
704 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
705 | },
706 | "node_modules/ioredis": {
707 | "version": "5.4.1",
708 | "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz",
709 | "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==",
710 | "dependencies": {
711 | "@ioredis/commands": "^1.1.1",
712 | "cluster-key-slot": "^1.1.0",
713 | "debug": "^4.3.4",
714 | "denque": "^2.1.0",
715 | "lodash.defaults": "^4.2.0",
716 | "lodash.isarguments": "^3.1.0",
717 | "redis-errors": "^1.2.0",
718 | "redis-parser": "^3.0.0",
719 | "standard-as-callback": "^2.1.0"
720 | },
721 | "engines": {
722 | "node": ">=12.22.0"
723 | },
724 | "funding": {
725 | "type": "opencollective",
726 | "url": "https://opencollective.com/ioredis"
727 | }
728 | },
729 | "node_modules/ioredis/node_modules/debug": {
730 | "version": "4.3.5",
731 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
732 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
733 | "dependencies": {
734 | "ms": "2.1.2"
735 | },
736 | "engines": {
737 | "node": ">=6.0"
738 | },
739 | "peerDependenciesMeta": {
740 | "supports-color": {
741 | "optional": true
742 | }
743 | }
744 | },
745 | "node_modules/ioredis/node_modules/ms": {
746 | "version": "2.1.2",
747 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
748 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
749 | },
750 | "node_modules/ipaddr.js": {
751 | "version": "1.9.1",
752 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
753 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
754 | "engines": {
755 | "node": ">= 0.10"
756 | }
757 | },
758 | "node_modules/jsonwebtoken": {
759 | "version": "9.0.2",
760 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
761 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
762 | "dependencies": {
763 | "jws": "^3.2.2",
764 | "lodash.includes": "^4.3.0",
765 | "lodash.isboolean": "^3.0.3",
766 | "lodash.isinteger": "^4.0.4",
767 | "lodash.isnumber": "^3.0.3",
768 | "lodash.isplainobject": "^4.0.6",
769 | "lodash.isstring": "^4.0.1",
770 | "lodash.once": "^4.0.0",
771 | "ms": "^2.1.1",
772 | "semver": "^7.5.4"
773 | },
774 | "engines": {
775 | "node": ">=12",
776 | "npm": ">=6"
777 | }
778 | },
779 | "node_modules/jsonwebtoken/node_modules/ms": {
780 | "version": "2.1.3",
781 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
782 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
783 | },
784 | "node_modules/jwa": {
785 | "version": "1.4.1",
786 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
787 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
788 | "dependencies": {
789 | "buffer-equal-constant-time": "1.0.1",
790 | "ecdsa-sig-formatter": "1.0.11",
791 | "safe-buffer": "^5.0.1"
792 | }
793 | },
794 | "node_modules/jws": {
795 | "version": "3.2.2",
796 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
797 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
798 | "dependencies": {
799 | "jwa": "^1.4.1",
800 | "safe-buffer": "^5.0.1"
801 | }
802 | },
803 | "node_modules/kareem": {
804 | "version": "2.6.3",
805 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
806 | "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
807 | "engines": {
808 | "node": ">=12.0.0"
809 | }
810 | },
811 | "node_modules/lodash": {
812 | "version": "4.17.21",
813 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
814 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
815 | },
816 | "node_modules/lodash.defaults": {
817 | "version": "4.2.0",
818 | "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
819 | "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
820 | },
821 | "node_modules/lodash.includes": {
822 | "version": "4.3.0",
823 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
824 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
825 | },
826 | "node_modules/lodash.isarguments": {
827 | "version": "3.1.0",
828 | "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
829 | "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="
830 | },
831 | "node_modules/lodash.isboolean": {
832 | "version": "3.0.3",
833 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
834 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
835 | },
836 | "node_modules/lodash.isinteger": {
837 | "version": "4.0.4",
838 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
839 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
840 | },
841 | "node_modules/lodash.isnumber": {
842 | "version": "3.0.3",
843 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
844 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
845 | },
846 | "node_modules/lodash.isplainobject": {
847 | "version": "4.0.6",
848 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
849 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
850 | },
851 | "node_modules/lodash.isstring": {
852 | "version": "4.0.1",
853 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
854 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
855 | },
856 | "node_modules/lodash.once": {
857 | "version": "4.1.1",
858 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
859 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
860 | },
861 | "node_modules/lodash.snakecase": {
862 | "version": "4.1.1",
863 | "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
864 | "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
865 | },
866 | "node_modules/magic-bytes.js": {
867 | "version": "1.10.0",
868 | "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz",
869 | "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="
870 | },
871 | "node_modules/media-typer": {
872 | "version": "0.3.0",
873 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
874 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
875 | "engines": {
876 | "node": ">= 0.6"
877 | }
878 | },
879 | "node_modules/memory-pager": {
880 | "version": "1.5.0",
881 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
882 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="
883 | },
884 | "node_modules/merge-descriptors": {
885 | "version": "1.0.1",
886 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
887 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
888 | },
889 | "node_modules/methods": {
890 | "version": "1.1.2",
891 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
892 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
893 | "engines": {
894 | "node": ">= 0.6"
895 | }
896 | },
897 | "node_modules/mime": {
898 | "version": "1.6.0",
899 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
900 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
901 | "bin": {
902 | "mime": "cli.js"
903 | },
904 | "engines": {
905 | "node": ">=4"
906 | }
907 | },
908 | "node_modules/mime-db": {
909 | "version": "1.52.0",
910 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
911 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
912 | "engines": {
913 | "node": ">= 0.6"
914 | }
915 | },
916 | "node_modules/mime-types": {
917 | "version": "2.1.35",
918 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
919 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
920 | "dependencies": {
921 | "mime-db": "1.52.0"
922 | },
923 | "engines": {
924 | "node": ">= 0.6"
925 | }
926 | },
927 | "node_modules/mongodb": {
928 | "version": "6.6.2",
929 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz",
930 | "integrity": "sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==",
931 | "dependencies": {
932 | "@mongodb-js/saslprep": "^1.1.5",
933 | "bson": "^6.7.0",
934 | "mongodb-connection-string-url": "^3.0.0"
935 | },
936 | "engines": {
937 | "node": ">=16.20.1"
938 | },
939 | "peerDependencies": {
940 | "@aws-sdk/credential-providers": "^3.188.0",
941 | "@mongodb-js/zstd": "^1.1.0",
942 | "gcp-metadata": "^5.2.0",
943 | "kerberos": "^2.0.1",
944 | "mongodb-client-encryption": ">=6.0.0 <7",
945 | "snappy": "^7.2.2",
946 | "socks": "^2.7.1"
947 | },
948 | "peerDependenciesMeta": {
949 | "@aws-sdk/credential-providers": {
950 | "optional": true
951 | },
952 | "@mongodb-js/zstd": {
953 | "optional": true
954 | },
955 | "gcp-metadata": {
956 | "optional": true
957 | },
958 | "kerberos": {
959 | "optional": true
960 | },
961 | "mongodb-client-encryption": {
962 | "optional": true
963 | },
964 | "snappy": {
965 | "optional": true
966 | },
967 | "socks": {
968 | "optional": true
969 | }
970 | }
971 | },
972 | "node_modules/mongodb-connection-string-url": {
973 | "version": "3.0.1",
974 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz",
975 | "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==",
976 | "dependencies": {
977 | "@types/whatwg-url": "^11.0.2",
978 | "whatwg-url": "^13.0.0"
979 | }
980 | },
981 | "node_modules/mongoose": {
982 | "version": "8.4.0",
983 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.0.tgz",
984 | "integrity": "sha512-fgqRMwVEP1qgRYfh+tUe2YBBFnPO35FIg2lfFH+w9IhRGg1/ataWGIqvf/MjwM29cZ60D5vSnqtN2b8Qp0sOZA==",
985 | "dependencies": {
986 | "bson": "^6.7.0",
987 | "kareem": "2.6.3",
988 | "mongodb": "6.6.2",
989 | "mpath": "0.9.0",
990 | "mquery": "5.0.0",
991 | "ms": "2.1.3",
992 | "sift": "17.1.3"
993 | },
994 | "engines": {
995 | "node": ">=16.20.1"
996 | },
997 | "funding": {
998 | "type": "opencollective",
999 | "url": "https://opencollective.com/mongoose"
1000 | }
1001 | },
1002 | "node_modules/mongoose/node_modules/ms": {
1003 | "version": "2.1.3",
1004 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1005 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1006 | },
1007 | "node_modules/mpath": {
1008 | "version": "0.9.0",
1009 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
1010 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
1011 | "engines": {
1012 | "node": ">=4.0.0"
1013 | }
1014 | },
1015 | "node_modules/mquery": {
1016 | "version": "5.0.0",
1017 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
1018 | "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
1019 | "dependencies": {
1020 | "debug": "4.x"
1021 | },
1022 | "engines": {
1023 | "node": ">=14.0.0"
1024 | }
1025 | },
1026 | "node_modules/mquery/node_modules/debug": {
1027 | "version": "4.3.4",
1028 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
1029 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
1030 | "dependencies": {
1031 | "ms": "2.1.2"
1032 | },
1033 | "engines": {
1034 | "node": ">=6.0"
1035 | },
1036 | "peerDependenciesMeta": {
1037 | "supports-color": {
1038 | "optional": true
1039 | }
1040 | }
1041 | },
1042 | "node_modules/mquery/node_modules/ms": {
1043 | "version": "2.1.2",
1044 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1045 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
1046 | },
1047 | "node_modules/ms": {
1048 | "version": "2.0.0",
1049 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1050 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1051 | },
1052 | "node_modules/negotiator": {
1053 | "version": "0.6.3",
1054 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1055 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
1056 | "engines": {
1057 | "node": ">= 0.6"
1058 | }
1059 | },
1060 | "node_modules/object-assign": {
1061 | "version": "4.1.1",
1062 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1063 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1064 | "engines": {
1065 | "node": ">=0.10.0"
1066 | }
1067 | },
1068 | "node_modules/object-inspect": {
1069 | "version": "1.13.1",
1070 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
1071 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
1072 | "funding": {
1073 | "url": "https://github.com/sponsors/ljharb"
1074 | }
1075 | },
1076 | "node_modules/on-finished": {
1077 | "version": "2.4.1",
1078 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1079 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1080 | "dependencies": {
1081 | "ee-first": "1.1.1"
1082 | },
1083 | "engines": {
1084 | "node": ">= 0.8"
1085 | }
1086 | },
1087 | "node_modules/parseurl": {
1088 | "version": "1.3.3",
1089 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1090 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1091 | "engines": {
1092 | "node": ">= 0.8"
1093 | }
1094 | },
1095 | "node_modules/path-to-regexp": {
1096 | "version": "0.1.7",
1097 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1098 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
1099 | },
1100 | "node_modules/proxy-addr": {
1101 | "version": "2.0.7",
1102 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1103 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1104 | "dependencies": {
1105 | "forwarded": "0.2.0",
1106 | "ipaddr.js": "1.9.1"
1107 | },
1108 | "engines": {
1109 | "node": ">= 0.10"
1110 | }
1111 | },
1112 | "node_modules/punycode": {
1113 | "version": "2.3.1",
1114 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
1115 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
1116 | "engines": {
1117 | "node": ">=6"
1118 | }
1119 | },
1120 | "node_modules/qs": {
1121 | "version": "6.11.0",
1122 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1123 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1124 | "dependencies": {
1125 | "side-channel": "^1.0.4"
1126 | },
1127 | "engines": {
1128 | "node": ">=0.6"
1129 | },
1130 | "funding": {
1131 | "url": "https://github.com/sponsors/ljharb"
1132 | }
1133 | },
1134 | "node_modules/range-parser": {
1135 | "version": "1.2.1",
1136 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1137 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1138 | "engines": {
1139 | "node": ">= 0.6"
1140 | }
1141 | },
1142 | "node_modules/raw-body": {
1143 | "version": "2.5.2",
1144 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
1145 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
1146 | "dependencies": {
1147 | "bytes": "3.1.2",
1148 | "http-errors": "2.0.0",
1149 | "iconv-lite": "0.4.24",
1150 | "unpipe": "1.0.0"
1151 | },
1152 | "engines": {
1153 | "node": ">= 0.8"
1154 | }
1155 | },
1156 | "node_modules/redis-errors": {
1157 | "version": "1.2.0",
1158 | "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
1159 | "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
1160 | "engines": {
1161 | "node": ">=4"
1162 | }
1163 | },
1164 | "node_modules/redis-parser": {
1165 | "version": "3.0.0",
1166 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
1167 | "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
1168 | "dependencies": {
1169 | "redis-errors": "^1.0.0"
1170 | },
1171 | "engines": {
1172 | "node": ">=4"
1173 | }
1174 | },
1175 | "node_modules/safe-buffer": {
1176 | "version": "5.2.1",
1177 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1178 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1179 | "funding": [
1180 | {
1181 | "type": "github",
1182 | "url": "https://github.com/sponsors/feross"
1183 | },
1184 | {
1185 | "type": "patreon",
1186 | "url": "https://www.patreon.com/feross"
1187 | },
1188 | {
1189 | "type": "consulting",
1190 | "url": "https://feross.org/support"
1191 | }
1192 | ]
1193 | },
1194 | "node_modules/safer-buffer": {
1195 | "version": "2.1.2",
1196 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1197 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1198 | },
1199 | "node_modules/semver": {
1200 | "version": "7.6.2",
1201 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
1202 | "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
1203 | "bin": {
1204 | "semver": "bin/semver.js"
1205 | },
1206 | "engines": {
1207 | "node": ">=10"
1208 | }
1209 | },
1210 | "node_modules/send": {
1211 | "version": "0.18.0",
1212 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1213 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1214 | "dependencies": {
1215 | "debug": "2.6.9",
1216 | "depd": "2.0.0",
1217 | "destroy": "1.2.0",
1218 | "encodeurl": "~1.0.2",
1219 | "escape-html": "~1.0.3",
1220 | "etag": "~1.8.1",
1221 | "fresh": "0.5.2",
1222 | "http-errors": "2.0.0",
1223 | "mime": "1.6.0",
1224 | "ms": "2.1.3",
1225 | "on-finished": "2.4.1",
1226 | "range-parser": "~1.2.1",
1227 | "statuses": "2.0.1"
1228 | },
1229 | "engines": {
1230 | "node": ">= 0.8.0"
1231 | }
1232 | },
1233 | "node_modules/send/node_modules/ms": {
1234 | "version": "2.1.3",
1235 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1236 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1237 | },
1238 | "node_modules/serve-static": {
1239 | "version": "1.15.0",
1240 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1241 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1242 | "dependencies": {
1243 | "encodeurl": "~1.0.2",
1244 | "escape-html": "~1.0.3",
1245 | "parseurl": "~1.3.3",
1246 | "send": "0.18.0"
1247 | },
1248 | "engines": {
1249 | "node": ">= 0.8.0"
1250 | }
1251 | },
1252 | "node_modules/set-function-length": {
1253 | "version": "1.2.2",
1254 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
1255 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
1256 | "dependencies": {
1257 | "define-data-property": "^1.1.4",
1258 | "es-errors": "^1.3.0",
1259 | "function-bind": "^1.1.2",
1260 | "get-intrinsic": "^1.2.4",
1261 | "gopd": "^1.0.1",
1262 | "has-property-descriptors": "^1.0.2"
1263 | },
1264 | "engines": {
1265 | "node": ">= 0.4"
1266 | }
1267 | },
1268 | "node_modules/setprototypeof": {
1269 | "version": "1.2.0",
1270 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1271 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1272 | },
1273 | "node_modules/side-channel": {
1274 | "version": "1.0.6",
1275 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
1276 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
1277 | "dependencies": {
1278 | "call-bind": "^1.0.7",
1279 | "es-errors": "^1.3.0",
1280 | "get-intrinsic": "^1.2.4",
1281 | "object-inspect": "^1.13.1"
1282 | },
1283 | "engines": {
1284 | "node": ">= 0.4"
1285 | },
1286 | "funding": {
1287 | "url": "https://github.com/sponsors/ljharb"
1288 | }
1289 | },
1290 | "node_modules/sift": {
1291 | "version": "17.1.3",
1292 | "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
1293 | "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ=="
1294 | },
1295 | "node_modules/sparse-bitfield": {
1296 | "version": "3.0.3",
1297 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
1298 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
1299 | "dependencies": {
1300 | "memory-pager": "^1.0.2"
1301 | }
1302 | },
1303 | "node_modules/standard-as-callback": {
1304 | "version": "2.1.0",
1305 | "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
1306 | "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
1307 | },
1308 | "node_modules/statuses": {
1309 | "version": "2.0.1",
1310 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1311 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1312 | "engines": {
1313 | "node": ">= 0.8"
1314 | }
1315 | },
1316 | "node_modules/toidentifier": {
1317 | "version": "1.0.1",
1318 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1319 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1320 | "engines": {
1321 | "node": ">=0.6"
1322 | }
1323 | },
1324 | "node_modules/tr46": {
1325 | "version": "4.1.1",
1326 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
1327 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
1328 | "dependencies": {
1329 | "punycode": "^2.3.0"
1330 | },
1331 | "engines": {
1332 | "node": ">=14"
1333 | }
1334 | },
1335 | "node_modules/ts-mixer": {
1336 | "version": "6.0.4",
1337 | "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
1338 | "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="
1339 | },
1340 | "node_modules/tslib": {
1341 | "version": "2.6.2",
1342 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
1343 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
1344 | },
1345 | "node_modules/type-is": {
1346 | "version": "1.6.18",
1347 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1348 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1349 | "dependencies": {
1350 | "media-typer": "0.3.0",
1351 | "mime-types": "~2.1.24"
1352 | },
1353 | "engines": {
1354 | "node": ">= 0.6"
1355 | }
1356 | },
1357 | "node_modules/undici": {
1358 | "version": "6.13.0",
1359 | "resolved": "https://registry.npmjs.org/undici/-/undici-6.13.0.tgz",
1360 | "integrity": "sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==",
1361 | "engines": {
1362 | "node": ">=18.0"
1363 | }
1364 | },
1365 | "node_modules/undici-types": {
1366 | "version": "5.26.5",
1367 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
1368 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
1369 | },
1370 | "node_modules/unpipe": {
1371 | "version": "1.0.0",
1372 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1373 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1374 | "engines": {
1375 | "node": ">= 0.8"
1376 | }
1377 | },
1378 | "node_modules/utils-merge": {
1379 | "version": "1.0.1",
1380 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1381 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
1382 | "engines": {
1383 | "node": ">= 0.4.0"
1384 | }
1385 | },
1386 | "node_modules/vary": {
1387 | "version": "1.1.2",
1388 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1389 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1390 | "engines": {
1391 | "node": ">= 0.8"
1392 | }
1393 | },
1394 | "node_modules/webidl-conversions": {
1395 | "version": "7.0.0",
1396 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
1397 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
1398 | "engines": {
1399 | "node": ">=12"
1400 | }
1401 | },
1402 | "node_modules/whatwg-url": {
1403 | "version": "13.0.0",
1404 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz",
1405 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==",
1406 | "dependencies": {
1407 | "tr46": "^4.1.1",
1408 | "webidl-conversions": "^7.0.0"
1409 | },
1410 | "engines": {
1411 | "node": ">=16"
1412 | }
1413 | },
1414 | "node_modules/ws": {
1415 | "version": "8.17.0",
1416 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
1417 | "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
1418 | "engines": {
1419 | "node": ">=10.0.0"
1420 | },
1421 | "peerDependencies": {
1422 | "bufferutil": "^4.0.1",
1423 | "utf-8-validate": ">=5.0.2"
1424 | },
1425 | "peerDependenciesMeta": {
1426 | "bufferutil": {
1427 | "optional": true
1428 | },
1429 | "utf-8-validate": {
1430 | "optional": true
1431 | }
1432 | }
1433 | }
1434 | }
1435 | }
1436 |
--------------------------------------------------------------------------------