From ea1965ef86fe3e1f34762159eed345f8974fc1c9 Mon Sep 17 00:00:00 2001 From: Arthur Dodin Date: Sun, 17 Aug 2025 20:41:51 +0200 Subject: [PATCH 01/10] feat: roadbook redirection --- frontend/package-lock.json | 18 ++++++++--------- frontend/package.json | 4 ++-- frontend/src/App.tsx | 26 ++++++++++++++----------- frontend/src/pages/RoadbookRedirect.tsx | 8 ++++++++ frontend/src/vite-env.d.ts | 1 + 5 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 frontend/src/pages/RoadbookRedirect.tsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 47a0acb..a11e448 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,9 +22,9 @@ "framer-motion": "^12.7.4", "jwt-decode": "^4.0.0", "lucide-react": "^0.488.0", - "react": "^19.1.0", + "react": "^19.1.1", "react-day-picker": "^8.10.1", - "react-dom": "^19.0.0", + "react-dom": "^19.1.1", "react-hook-form": "^7.55.0", "react-icons": "^5.5.0", "react-router-dom": "^7.5.0", @@ -4963,9 +4963,9 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", + "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4986,15 +4986,15 @@ } }, "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", + "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", "license": "MIT", "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19.1.1" } }, "node_modules/react-hook-form": { diff --git a/frontend/package.json b/frontend/package.json index 8c85ac7..aad90f4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,9 +24,9 @@ "framer-motion": "^12.7.4", "jwt-decode": "^4.0.0", "lucide-react": "^0.488.0", - "react": "^19.1.0", + "react": "^19.1.1", "react-day-picker": "^8.10.1", - "react-dom": "^19.0.0", + "react-dom": "^19.1.1", "react-hook-form": "^7.55.0", "react-icons": "^5.5.0", "react-router-dom": "^7.5.0", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8f6d4cc..88c1e79 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,16 +6,18 @@ import LoginPage from './pages/Auth'; import { HomePage } from './pages/Home'; import { ProfilPage } from './pages/Profil'; import { ShotgunPage } from './pages/Shotgun'; -import { AdminPageRole, - AdminPageTeam, - AdminPageEvents, - AdminPageExport, - AdminPageFaction, - AdminPagePerm, - AdminPageChall, - AdminPageEmail, - AdminPageUser, - AdminPageNews } from './pages/Admin'; +import { + AdminPageRole, + AdminPageTeam, + AdminPageEvents, + AdminPageExport, + AdminPageFaction, + AdminPagePerm, + AdminPageChall, + AdminPageEmail, + AdminPageUser, + AdminPageNews +} from './pages/Admin'; import ProtectedRoute from './components/utils/protectedroute'; import AdminRoute from './components/utils/adminroute'; @@ -27,7 +29,8 @@ import { ResetPasswordPage } from './pages/ResetPassword' import { WeiPage } from './pages/Wei'; import { SdiPage } from './pages/Sdi'; import { NewsPage } from './pages/News'; -import {DiscordPage} from './pages/Discord'; +import { DiscordPage } from './pages/Discord'; +import { RoadbookRedirect } from './pages/RoadbookRedirect'; import PrivateRoute from './components/utils/privateroute'; @@ -54,6 +57,7 @@ const App: React.FC = () => { } /> } /> } /> + } /> {/* Utilisateurs connectés */} } /> diff --git a/frontend/src/pages/RoadbookRedirect.tsx b/frontend/src/pages/RoadbookRedirect.tsx new file mode 100644 index 0000000..08991c2 --- /dev/null +++ b/frontend/src/pages/RoadbookRedirect.tsx @@ -0,0 +1,8 @@ +import React from "react"; + +export const RoadbookRedirect: React.FC = () => { + React.useEffect(() => { + window.location.href = import.meta.env.VITE_ROADBOOK_URL; + }, []); + return null; +}; \ No newline at end of file diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index c619b5f..8dd80d6 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -3,3 +3,4 @@ VITE_SERVICE_URL = "https://integration.utt.fr/" VITE_CAS_LOGIN_URL = "https://cas.utt.fr/cas/login" VITE_API_URL = "http://localhost:4001/api" VITE_ANALYTICS_WEBSITE_ID = "" +VITE_ROADBOOK_URL = "" From b8e1774a780ca9f7b45bd1fe976d0106ec2870a5 Mon Sep 17 00:00:00 2001 From: Arthur Dodin Date: Sun, 17 Aug 2025 21:43:16 +0200 Subject: [PATCH 02/10] update: add redirection text --- frontend/src/pages/RoadbookRedirect.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/RoadbookRedirect.tsx b/frontend/src/pages/RoadbookRedirect.tsx index 08991c2..08e18a3 100644 --- a/frontend/src/pages/RoadbookRedirect.tsx +++ b/frontend/src/pages/RoadbookRedirect.tsx @@ -4,5 +4,11 @@ export const RoadbookRedirect: React.FC = () => { React.useEffect(() => { window.location.href = import.meta.env.VITE_ROADBOOK_URL; }, []); - return null; + return ( +
+
+ Redirection en cours... +
+
+ ); }; \ No newline at end of file From a64b400d9be53d8c677395f0ddda6c0eb9ef9422 Mon Sep 17 00:00:00 2001 From: Arthur Dodin Date: Sun, 17 Aug 2025 21:43:57 +0200 Subject: [PATCH 03/10] feat: roadbook section on home page --- frontend/src/components/home/infosSection.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/frontend/src/components/home/infosSection.tsx b/frontend/src/components/home/infosSection.tsx index d647065..1688e5c 100644 --- a/frontend/src/components/home/infosSection.tsx +++ b/frontend/src/components/home/infosSection.tsx @@ -1,5 +1,7 @@ import { Swiper, SwiperSlide } from "swiper/react"; import { Pagination, Autoplay } from "swiper/modules"; +import { Button } from "../ui/button"; +import { Link } from "react-router-dom"; import "swiper/swiper-bundle.css"; export const Infos = () => { @@ -79,6 +81,20 @@ export const Infos = () => { C'est ici que tu trouveras toutes les informations nécessaires au déroulement de la semaine d'inté. Par exemple, tu pourras prendre ta place pour le WEI ou regarder quelle faction est la plus proche de la victoire.

+ +
+

+ Le Roadbook de l'inté +

+

+ Retrouve ici toutes les informations de l’intégration ! Les plannings, la prévention, les activités, les menus… Tout pour passer des moments incroyables ! +

+ +
From f69b98fff4dd2e8eb79b01fb5a53d1439d4452cf Mon Sep 17 00:00:00 2001 From: Arthur Dodin Date: Sun, 17 Aug 2025 23:01:34 +0200 Subject: [PATCH 04/10] update: add VITE_ROADBOOK_URL in ci --- .github/workflows/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fd13bbf..ab85ead 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,6 @@ on: - dev jobs: - deploy-api: runs-on: self-hosted @@ -59,5 +58,6 @@ jobs: VITE_API_URL=${{ github.ref == 'refs/heads/prod' && 'https://integration.utt.fr/api' || 'https://integration.dev.uttnetgroup.fr/api' }} VITE_SERVICE_URL=${{ github.ref == 'refs/heads/prod' && 'https://integration.utt.fr/' || 'https://integration.dev.uttnetgroup.fr/' }} VITE_ANALYTICS_WEBSITE_ID=${{ github.ref == 'refs/heads/prod' && secrets.ANALYTICS_WEBSITE_ID_PROD || secrets.ANALYTICS_WEBSITE_ID_DEV }} + VITE_ROADBOOK_URL=${{ secrets.ROADBOOK_URL }} tags: | - ${{ secrets.REGISTRY_URL }}/integration/front:${{ github.ref == 'refs/heads/prod' && 'prod' || 'dev' }} \ No newline at end of file + ${{ secrets.REGISTRY_URL }}/integration/front:${{ github.ref == 'refs/heads/prod' && 'prod' || 'dev' }} From 9c44dc0ab0e0376e8a9cf3328c8ffec10e9100eb Mon Sep 17 00:00:00 2001 From: Arthur Dodin Date: Tue, 26 Aug 2025 18:47:03 +0200 Subject: [PATCH 05/10] update: switch to real page --- .github/workflows/ci.yaml | 3 +- frontend/src/App.tsx | 4 +- .../src/components/roadbook/roadbookLinks.tsx | 39 +++++++++++++++++++ frontend/src/pages/Roadbook.tsx | 18 +++++++++ frontend/src/pages/RoadbookRedirect.tsx | 14 ------- frontend/src/vite-env.d.ts | 3 +- 6 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 frontend/src/components/roadbook/roadbookLinks.tsx create mode 100644 frontend/src/pages/Roadbook.tsx delete mode 100644 frontend/src/pages/RoadbookRedirect.tsx diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ab85ead..63d15c2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -58,6 +58,7 @@ jobs: VITE_API_URL=${{ github.ref == 'refs/heads/prod' && 'https://integration.utt.fr/api' || 'https://integration.dev.uttnetgroup.fr/api' }} VITE_SERVICE_URL=${{ github.ref == 'refs/heads/prod' && 'https://integration.utt.fr/' || 'https://integration.dev.uttnetgroup.fr/' }} VITE_ANALYTICS_WEBSITE_ID=${{ github.ref == 'refs/heads/prod' && secrets.ANALYTICS_WEBSITE_ID_PROD || secrets.ANALYTICS_WEBSITE_ID_DEV }} - VITE_ROADBOOK_URL=${{ secrets.ROADBOOK_URL }} + VITE_ROADBOOK_URL_FRENCH=${{ secrets.ROADBOOK_URL_FRENCH }} + VITE_ROADBOOK_URL_ENGLISH=${{ secrets.ROADBOOK_URL_ENGLISH }} tags: | ${{ secrets.REGISTRY_URL }}/integration/front:${{ github.ref == 'refs/heads/prod' && 'prod' || 'dev' }} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a0f7712..db1fe25 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -31,7 +31,7 @@ import { WeiPage } from './pages/Wei'; import { SdiPage } from './pages/Sdi'; import { NewsPage } from './pages/News'; import { DiscordPage } from './pages/Discord'; -import { RoadbookRedirect } from './pages/RoadbookRedirect'; +import { Roadbook } from './pages/Roadbook'; import PrivateRoute from './components/utils/privateroute'; import { GamesPage } from './pages/Games'; import { FoodPage } from './pages/Food'; @@ -60,7 +60,7 @@ const App: React.FC = () => { } /> } /> } /> - } /> + } /> {/* Utilisateurs connectés */} } /> diff --git a/frontend/src/components/roadbook/roadbookLinks.tsx b/frontend/src/components/roadbook/roadbookLinks.tsx new file mode 100644 index 0000000..e4fc046 --- /dev/null +++ b/frontend/src/components/roadbook/roadbookLinks.tsx @@ -0,0 +1,39 @@ +import { Button } from "../ui/button"; +import { Card } from "../ui/card"; +import { Link } from "react-router-dom"; + +export const RoadBookLinks = () => { + + return ( +
+ +

+ 📖{" "} + Roadbook de l'intégration{" "} + 🚗 +

+ + +
+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae veritatis, ratione eaque exercitationem laborum nisi at, neque modi vel culpa nam corporis et alias reiciendis voluptatibus ullam. Sequi, iure vero! Lorem ipsum dolor sit amet consectetur adipisicing elit. Beatae fugit iusto illo. Laboriosam modi distinctio accusamus provident ipsum esse delectus voluptatum. Illum, ab distinctio. Ut deleniti at iste cupiditate consectetur. Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente accusamus illum dolor expedita sint deleniti sed, iure aperiam. Eligendi ipsam commodi dicta hic, modi mollitia molestias repellat quam repellendus fugit.

+
+ +
+ + + + {/* + + */} +

An english version will be available soon !

+
+
+
+ ); +}; + diff --git a/frontend/src/pages/Roadbook.tsx b/frontend/src/pages/Roadbook.tsx new file mode 100644 index 0000000..905678f --- /dev/null +++ b/frontend/src/pages/Roadbook.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { RoadBookLinks } from "../components/roadbook/roadbookLinks"; + +export const Roadbook: React.FC = () => { + return ( +
+
+
+ +
+
+

+
+

© 2025 Semaine d'Intégration UTT

+
+
+ ); +}; \ No newline at end of file diff --git a/frontend/src/pages/RoadbookRedirect.tsx b/frontend/src/pages/RoadbookRedirect.tsx deleted file mode 100644 index 08e18a3..0000000 --- a/frontend/src/pages/RoadbookRedirect.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from "react"; - -export const RoadbookRedirect: React.FC = () => { - React.useEffect(() => { - window.location.href = import.meta.env.VITE_ROADBOOK_URL; - }, []); - return ( -
-
- Redirection en cours... -
-
- ); -}; \ No newline at end of file diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 8dd80d6..377343f 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -3,4 +3,5 @@ VITE_SERVICE_URL = "https://integration.utt.fr/" VITE_CAS_LOGIN_URL = "https://cas.utt.fr/cas/login" VITE_API_URL = "http://localhost:4001/api" VITE_ANALYTICS_WEBSITE_ID = "" -VITE_ROADBOOK_URL = "" +VITE_ROADBOOK_URL_FRENCH = "" +VITE_ROADBOOK_URL_ENGLISH = "" From ea7c3a107c9626ea50b7033982876bb55b3986ac Mon Sep 17 00:00:00 2001 From: Arthur Dodin Date: Tue, 26 Aug 2025 19:03:14 +0200 Subject: [PATCH 06/10] Merge branch 'prod' into roadbook --- .gitignore | 1 + backend/package-lock.json | 166 + backend/package.json | 2 + backend/server.ts | 10 +- backend/src/controllers/email.controller.ts | 21 +- backend/src/controllers/event.controller.ts | 23 +- backend/src/controllers/export.controller.ts | 83 - .../src/controllers/im_export.controller.ts | 168 + .../src/controllers/permanence.controller.ts | 74 +- backend/src/controllers/team.controller.ts | 162 +- backend/src/controllers/tent.controller.ts | 113 + backend/src/controllers/user.controller.ts | 8 +- backend/src/database/db.ts | 81 +- backend/src/database/initdb/initevent.ts | 8 +- backend/src/database/initdb/initrole.ts | 1 + .../migrations/0017_melted_meggan.sql | 1 + .../migrations/0018_puzzling_arachne.sql | 1 + .../migrations/0019_complete_moondragon.sql | 2 + .../0020_strange_colonel_america.sql | 8 + .../migrations/0021_colossal_madame_web.sql | 10 + .../migrations/meta/0017_snapshot.json | 1124 +++++++ .../migrations/meta/0018_snapshot.json | 1131 +++++++ .../migrations/meta/0019_snapshot.json | 1144 +++++++ .../migrations/meta/0020_snapshot.json | 1204 +++++++ .../migrations/meta/0021_snapshot.json | 1278 ++++++++ .../database/migrations/meta/_journal.json | 35 + backend/src/middlewares/multer.middleware.ts | 115 +- .../src/middlewares/respoperm.middleware.ts | 29 + backend/src/routes/event.routes.ts | 2 + backend/src/routes/export.routes.ts | 12 - backend/src/routes/im_export.routes.ts | 19 + backend/src/routes/news.routes.ts | 9 +- backend/src/routes/permanences.routes.ts | 8 +- backend/src/routes/tent.routes.ts | 21 + backend/src/routes/user.routes.ts | 7 +- backend/src/schemas/Basic/event.schema.ts | 3 +- .../src/schemas/Basic/permanence.schema.ts | 3 +- .../Relational/userpermanences.schema.ts | 13 +- .../src/schemas/Relational/usertent.schema.ts | 14 + backend/src/services/event.service.ts | 6 + backend/src/services/export.service.ts | 39 - backend/src/services/im_export.service.ts | 87 + backend/src/services/permanence.service.ts | 221 +- backend/src/services/tent.service.ts | 136 + backend/src/services/user.service.ts | 54 +- backend/src/utils/emailtemplates.ts | 31 + backend/src/utils/no_sync_list.ts | 4 + frontend/Dockerfile | 2 +- frontend/package-lock.json | 2896 ++++++++++++++++- frontend/package.json | 12 +- frontend/src/App.tsx | 43 +- .../AdminChallenge/adminChalengeList.tsx | 69 + .../adminChallengeAddPointsForm.tsx | 102 + .../AdminChallenge/adminChallengeEditor.tsx | 110 + .../adminChallengeValidatedList.tsx | 106 + .../Admin/AdminPerm/adminPermAction.tsx | 87 + .../Admin/AdminPerm/adminPermForm.tsx | 220 ++ .../Admin/AdminPerm/adminPermImport.tsx | 90 + .../Admin/AdminPerm/adminPermList.tsx | 139 + .../Admin/AdminPerm/adminPermMembers.tsx | 195 ++ .../src/components/Admin/adminChallenge.tsx | 483 --- frontend/src/components/Admin/adminEvent.tsx | 270 +- .../components/Admin/adminExportImport.tsx | 351 +- frontend/src/components/Admin/adminNews.tsx | 4 +- frontend/src/components/Admin/adminPerm.tsx | 382 --- frontend/src/components/Admin/adminTeam.tsx | 2 +- frontend/src/components/Admin/adminTent.tsx | 199 ++ frontend/src/components/Admin/adminUser.tsx | 173 +- .../components/Plannings/planningSection.tsx | 110 + .../components/WEI_SDI_Food/foodSection.tsx | 69 +- .../components/challenge/challengeList.tsx | 43 +- frontend/src/components/navbar.tsx | 429 +-- frontend/src/components/news/newsSection.tsx | 2 +- .../src/components/permanence/appealPerm.tsx | 186 ++ .../src/components/permanence/permForm.tsx | 171 - .../src/components/permanence/permList.tsx | 82 + .../src/components/permanence/permUser.tsx | 85 + frontend/src/components/tent/tentSection.tsx | 211 ++ frontend/src/components/ui/accordion.tsx | 64 + frontend/src/components/ui/calendar.tsx | 73 - .../src/components/utils/datetime_utils.ts | 33 +- .../src/interfaces/permanence.interface.ts | 13 +- frontend/src/interfaces/tent.interface.ts | 6 + frontend/src/pages/Admin.tsx | 159 - frontend/src/pages/Event.tsx | 0 frontend/src/pages/Perm.tsx | 17 - frontend/src/pages/admin.tsx | 368 +++ frontend/src/pages/{Auth.tsx => auth.tsx} | 0 .../pages/{Challenge.tsx => challenge.tsx} | 4 +- .../src/pages/{Discord.tsx => discord.tsx} | 0 frontend/src/pages/{Food.tsx => food.tsx} | 0 frontend/src/pages/{Games.tsx => games.tsx} | 0 frontend/src/pages/{Home.tsx => home.tsx} | 0 frontend/src/pages/{News.tsx => news.tsx} | 0 .../pages/{Parrainage.tsx => parrainage.tsx} | 0 frontend/src/pages/perm.tsx | 201 ++ frontend/src/pages/{Wei.tsx => plannings.tsx} | 15 +- frontend/src/pages/{Profil.tsx => profil.tsx} | 2 +- .../src/pages/{Register.tsx => register.tsx} | 0 .../{ResetPassword.tsx => resetPassword.tsx} | 0 frontend/src/pages/{Sdi.tsx => sdi.tsx} | 0 .../src/pages/{Shotgun.tsx => shotgun.tsx} | 0 frontend/src/pages/wei.tsx | 31 + .../src/services/requests/event.service.ts | 15 + .../src/services/requests/export.service.ts | 9 - .../services/requests/im_export.service.ts | 27 + .../services/requests/permanence.service.ts | 33 + .../src/services/requests/tent.service.ts | 39 + .../src/services/requests/user.service.ts | 2 +- 109 files changed, 13750 insertions(+), 2376 deletions(-) delete mode 100644 backend/src/controllers/export.controller.ts create mode 100644 backend/src/controllers/im_export.controller.ts create mode 100644 backend/src/controllers/tent.controller.ts create mode 100644 backend/src/database/migrations/0017_melted_meggan.sql create mode 100644 backend/src/database/migrations/0018_puzzling_arachne.sql create mode 100644 backend/src/database/migrations/0019_complete_moondragon.sql create mode 100644 backend/src/database/migrations/0020_strange_colonel_america.sql create mode 100644 backend/src/database/migrations/0021_colossal_madame_web.sql create mode 100644 backend/src/database/migrations/meta/0017_snapshot.json create mode 100644 backend/src/database/migrations/meta/0018_snapshot.json create mode 100644 backend/src/database/migrations/meta/0019_snapshot.json create mode 100644 backend/src/database/migrations/meta/0020_snapshot.json create mode 100644 backend/src/database/migrations/meta/0021_snapshot.json create mode 100644 backend/src/middlewares/respoperm.middleware.ts delete mode 100644 backend/src/routes/export.routes.ts create mode 100644 backend/src/routes/im_export.routes.ts create mode 100644 backend/src/routes/tent.routes.ts create mode 100644 backend/src/schemas/Relational/usertent.schema.ts delete mode 100644 backend/src/services/export.service.ts create mode 100644 backend/src/services/im_export.service.ts create mode 100644 backend/src/services/tent.service.ts create mode 100644 backend/src/utils/no_sync_list.ts create mode 100644 frontend/src/components/Admin/AdminChallenge/adminChalengeList.tsx create mode 100644 frontend/src/components/Admin/AdminChallenge/adminChallengeAddPointsForm.tsx create mode 100644 frontend/src/components/Admin/AdminChallenge/adminChallengeEditor.tsx create mode 100644 frontend/src/components/Admin/AdminChallenge/adminChallengeValidatedList.tsx create mode 100644 frontend/src/components/Admin/AdminPerm/adminPermAction.tsx create mode 100644 frontend/src/components/Admin/AdminPerm/adminPermForm.tsx create mode 100644 frontend/src/components/Admin/AdminPerm/adminPermImport.tsx create mode 100644 frontend/src/components/Admin/AdminPerm/adminPermList.tsx create mode 100644 frontend/src/components/Admin/AdminPerm/adminPermMembers.tsx delete mode 100644 frontend/src/components/Admin/adminChallenge.tsx delete mode 100644 frontend/src/components/Admin/adminPerm.tsx create mode 100644 frontend/src/components/Admin/adminTent.tsx create mode 100644 frontend/src/components/Plannings/planningSection.tsx create mode 100644 frontend/src/components/permanence/appealPerm.tsx delete mode 100644 frontend/src/components/permanence/permForm.tsx create mode 100644 frontend/src/components/permanence/permList.tsx create mode 100644 frontend/src/components/permanence/permUser.tsx create mode 100644 frontend/src/components/tent/tentSection.tsx create mode 100644 frontend/src/components/ui/accordion.tsx delete mode 100644 frontend/src/components/ui/calendar.tsx create mode 100644 frontend/src/interfaces/tent.interface.ts delete mode 100644 frontend/src/pages/Admin.tsx delete mode 100644 frontend/src/pages/Event.tsx delete mode 100644 frontend/src/pages/Perm.tsx create mode 100644 frontend/src/pages/admin.tsx rename frontend/src/pages/{Auth.tsx => auth.tsx} (100%) rename frontend/src/pages/{Challenge.tsx => challenge.tsx} (79%) rename frontend/src/pages/{Discord.tsx => discord.tsx} (100%) rename frontend/src/pages/{Food.tsx => food.tsx} (100%) rename frontend/src/pages/{Games.tsx => games.tsx} (100%) rename frontend/src/pages/{Home.tsx => home.tsx} (100%) rename frontend/src/pages/{News.tsx => news.tsx} (100%) rename frontend/src/pages/{Parrainage.tsx => parrainage.tsx} (100%) create mode 100644 frontend/src/pages/perm.tsx rename frontend/src/pages/{Wei.tsx => plannings.tsx} (59%) rename frontend/src/pages/{Profil.tsx => profil.tsx} (99%) rename frontend/src/pages/{Register.tsx => register.tsx} (100%) rename frontend/src/pages/{ResetPassword.tsx => resetPassword.tsx} (100%) rename frontend/src/pages/{Sdi.tsx => sdi.tsx} (100%) rename frontend/src/pages/{Shotgun.tsx => shotgun.tsx} (100%) create mode 100644 frontend/src/pages/wei.tsx delete mode 100644 frontend/src/services/requests/export.service.ts create mode 100644 frontend/src/services/requests/im_export.service.ts create mode 100644 frontend/src/services/requests/tent.service.ts diff --git a/.gitignore b/.gitignore index 73a69e7..9b6f36d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ frontend/node_modules/ # Ignorer les node_modules du backend backend/node_modules/ backend/uploads/ +backend/exports/ # Autres fichiers à ignorer .DS_Store diff --git a/backend/package-lock.json b/backend/package-lock.json index e0327f1..995d024 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -22,9 +22,11 @@ "esbuild": "^0.25.2", "esbuild-register": "^3.6.0", "express": "^5.1.0", + "file-type": "^21.0.0", "googleapis": "^148.0.0", "handlebars": "^4.7.8", "jsdom": "^26.1.0", + "json2csv": "^6.0.0-alpha.2", "jsonwebtoken": "^9.0.2", "multer": "^1.4.5-lts.2", "nodemailer": "^6.10.1", @@ -61,6 +63,16 @@ "lru-cache": "^10.4.3" } }, + "node_modules/@borewit/text-codec": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", + "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -1057,6 +1069,36 @@ "integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==", "license": "MIT" }, + "node_modules/@streamparser/json": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.6.tgz", + "integrity": "sha512-vL9EVn/v+OhZ+Wcs6O4iKE9EUpwHUqHmCtNUMWjqp+6dr85+XPOSGTEsqYNq1Vn04uk9SWlOVmx9J48ggJVT2Q==", + "license": "MIT" + }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -1532,6 +1574,15 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2562,6 +2613,30 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, + "node_modules/file-type": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz", + "integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.2.7", + "strtok3": "^10.2.2", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -3060,6 +3135,26 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -3224,6 +3319,24 @@ "bignumber.js": "^9.0.0" } }, + "node_modules/json2csv": { + "version": "6.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-6.0.0-alpha.2.tgz", + "integrity": "sha512-nJ3oP6QxN8z69IT1HmrJdfVxhU1kLTBVgMfRnNZc37YEY+jZ4nU27rBGxT4vaqM/KUCavLRhntmTuBFqZLBUcA==", + "license": "MIT", + "dependencies": { + "@streamparser/json": "^0.0.6", + "commander": "^6.2.0", + "lodash.get": "^4.4.2" + }, + "bin": { + "json2csv": "bin/json2csv.js" + }, + "engines": { + "node": ">= 12", + "npm": ">= 6.13.0" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -3288,6 +3401,13 @@ "safe-buffer": "^5.0.1" } }, + "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==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -4398,6 +4518,22 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, + "node_modules/strtok3": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -4457,6 +4593,24 @@ "node": ">=0.6" } }, + "node_modules/token-types": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.1.tgz", + "integrity": "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.1.0", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/touch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", @@ -4602,6 +4756,18 @@ "node": ">=0.8.0" } }, + "node_modules/uint8array-extras": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.1.tgz", + "integrity": "sha512-+NWHrac9dvilNgme+gP4YrBSumsaMZP0fNBtXXFIf33RLLKEcBUKaQZ7ULUbS0sBfcjxIZ4V96OTRkCbM7hxpw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", diff --git a/backend/package.json b/backend/package.json index fa1aa0b..91fb766 100644 --- a/backend/package.json +++ b/backend/package.json @@ -31,9 +31,11 @@ "esbuild": "^0.25.2", "esbuild-register": "^3.6.0", "express": "^5.1.0", + "file-type": "^21.0.0", "googleapis": "^148.0.0", "handlebars": "^4.7.8", "jsdom": "^26.1.0", + "json2csv": "^6.0.0-alpha.2", "jsonwebtoken": "^9.0.2", "multer": "^1.4.5-lts.2", "nodemailer": "^6.10.1", diff --git a/backend/server.ts b/backend/server.ts index dbf65a4..0bea7a9 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -11,19 +11,19 @@ import userRoutes from './src/routes/user.routes'; import teamRoutes from './src/routes/team.routes'; import eventRoutes from './src/routes/event.routes'; import factionRoutes from './src/routes/faction.routes'; -import exportRoutes from './src/routes/export.routes'; +import imexportRouter from './src/routes/im_export.routes'; import permanenceRoutes from './src/routes/permanences.routes'; import challengeRoutes from './src/routes/challenge.routes'; import emailRoutes from './src/routes/email.routes'; import newsRoutes from './src/routes/news.routes'; import discordRoutes from './src/routes/discord.routes'; +import tentRoutes from './src/routes/tent.routes'; import { server_port } from './src/utils/secret'; import { initUser } from './src/database/initdb/initUser' import { initRoles } from './src/database/initdb/initrole' import {initEvent} from './src/database/initdb/initevent' import {initChallenge} from './src/database/initdb/initChallenge' import { authenticateUser } from './src/middlewares/auth.middleware'; -//import { initDB } from './src/database/init'; dotenv.config(); @@ -51,13 +51,17 @@ async function startServer() { app.use('/api/team',authenticateUser, teamRoutes); app.use('/api/event',authenticateUser, eventRoutes); app.use('/api/faction',authenticateUser, factionRoutes); - app.use('/api/export',authenticateUser, exportRoutes); + app.use('/api/imexport', authenticateUser, imexportRouter) app.use('/api/permanence',authenticateUser, permanenceRoutes); app.use('/api/challenge',authenticateUser, challengeRoutes); app.use('/api/email',authenticateUser, emailRoutes); app.use('/api/news',authenticateUser, newsRoutes); app.use('/api/discord',authenticateUser, discordRoutes); + app.use('/api/tent',authenticateUser, tentRoutes); app.use("/api/uploads/imgnews", express.static(path.join(__dirname, "/uploads/imgnews"))); + app.use("/api/uploads/foodmenu", express.static(path.join(__dirname, "/uploads/foodmenu"))); + app.use("/api/uploads/plannings", express.static(path.join(__dirname, "/uploads/plannings"))); + app.use("/api/exports/bus", express.static(path.join(__dirname, "/exports/bus"))); // Démarrage du serveur app.listen(server_port, () => { diff --git a/backend/src/controllers/email.controller.ts b/backend/src/controllers/email.controller.ts index 90dfc13..919d61e 100644 --- a/backend/src/controllers/email.controller.ts +++ b/backend/src/controllers/email.controller.ts @@ -17,16 +17,29 @@ export interface EmailOptions { } // Fonction pour générer l'HTML à partir du template -export const generateEmailHtml = (templateName: string, data: any) => { +export const generateEmailHtml = (templateName: string, data: any) => { switch (templateName) { case 'templateNotebook': - return template.compileTemplate({ notebook: data.notebook }, template.templateNotebook); + return template.compileTemplate({ notebook: data.notebook }, template.templateNotebook); + case 'templateAttributionBus': - return template.compileTemplate({ bus: data.bus, time: data.tim }, template.templateAttributionBus); + return template.compileTemplate({ bus: data.bus, time: data.time }, template.templateAttributionBus); + case 'templateWelcome': return template.compileTemplate({ token: data.token }, template.templateWelcome); + case 'templateNotifyNews': - return template.compileTemplate({title: data.title, description: data.description,}, template.templateNotifyNews); + return template.compileTemplate( + { title: data.title, description: data.description }, + template.templateNotifyNews + ); + + case 'templateNotifyTentConfirmation': + return template.compileTemplate( + { user1: data.user1, user2: data.user2, confirmed: data.confirmed }, + template.templateNotifyTentConfirmation + ); + default: return null; } diff --git a/backend/src/controllers/event.controller.ts b/backend/src/controllers/event.controller.ts index b957d0b..72399f4 100644 --- a/backend/src/controllers/event.controller.ts +++ b/backend/src/controllers/event.controller.ts @@ -51,7 +51,17 @@ export const checkFoodStatus = async (req: Request, res: Response) => { Ok(res, ({data: status?.food_open})); }catch(error){ - Error(res, {msg :"Error while catching WEI status :" + error}) + Error(res, {msg :"Error while catching Food status :" + error}) + } +}; + +export const checkChallStatus = async (req: Request, res: Response) => { + try{ + const status = await event_service.getEventsStatus(); + Ok(res, ({data: status?.chall_open})); + + }catch(error){ + Error(res, {msg :"Error while catching Challenge status :" + error}) } }; @@ -142,4 +152,15 @@ export const toggleFood = async (req: Request, res: Response) => { } catch (error) { Error(res,{ msg: "Erreur lors de la mise à jour." }); } +}; + +export const toggleChall = async (req: Request, res: Response) => { + const { challOpen } = req.body; + + try { + const result = await event_service.updateChallStatus(challOpen); + Ok(res,{ msg: "Paramètres mis à jour.", data: result }); + } catch (error) { + Error(res,{ msg: "Erreur lors de la mise à jour." }); + } }; \ No newline at end of file diff --git a/backend/src/controllers/export.controller.ts b/backend/src/controllers/export.controller.ts deleted file mode 100644 index 5e15cea..0000000 --- a/backend/src/controllers/export.controller.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Request, Response } from "express"; -import * as export_service from "../services/export.service"; -import * as user_service from '../services/user.service'; -import * as team_service from "../services/team.service"; -import * as permanence_service from "../services/permanence.service"; -import * as event_service from "../services/event.service"; -import { spreadsheet_id } from "../utils/secret"; -import { Ok, Error } from "../utils/responses"; - -export const exportAllDataToSheets = async (req: Request, res: Response) => { - try { - // 1. Récupération depuis la DB - const userList = await user_service.getUsersAll(); - const teamList = await team_service.getTeamsAll(); - const permanenceList = await permanence_service.getAllPermanencesWithUsers(); - const shotgunList = await event_service.getAllTeamShotguns(); - - - // 2. Mapping -> format pour Google Sheets (array de array) - const usersValues = [ - ["ID", "Prénom", "Nom", "Email", "Branche", "Permission", "Majeur", "Contact","Discord", "Team", "Faction"], - ...userList.map(u => [ - u.id ?? 0, - u.first_name ?? "No first name", - u.last_name ?? "No last name", - u.email ?? "No email", - u.branch ?? "No branch", - u.permission ?? "No permissions", - u.majeur ?? "Pas de données", - u.contact ?? "No contact", - u.discord_id ?? "No discord ID", - u.teamName ?? "No Team", - u.factionName ?? "No faction" - ]) - ]; - - const teamsValues = [ - ["ID", "Nom", "Type", "Faction"], - ...teamList.map(t => [ - t.id, - t.name ?? "No name", - t.type ?? "No type", - t.teamFaction?.name ?? "No faction" - ]) - ]; - - const permanenceValues = [ - ["ID", "Nom", "Début", "Fin", "Lieu", "Inscrits (noms)","Inscrits (emails)"], - ...permanenceList.map(p => [ - p.id, - p.name ?? "Sans nom", - p.start_at?.toISOString() ?? "N/A", - p.end_at?.toISOString() ?? "N/A", - p.location ?? "Sans lieu", - p.users.map(u => `${u.first_name} ${u.last_name}`).join(" ; ") || "Aucun inscrit", - p.users.map(u => (u.email)).join(" ; ") || "Aucun inscrit" - ]) - ]; - - - const shotgunValues = [ - ["ID", "Nom de l'équipe", "Type", "Horodatage"], - ...shotgunList.map(s => [ - s.id, - s.teamName ?? "No name", - s.teamType ?? "No type", - s.timestamp?.toISOString() ?? "No timestamp" - ]) - ]; - // 3. Envoi vers les feuilles - await export_service.writeToGoogleSheet(spreadsheet_id, "USER!A1", usersValues); - await export_service.writeToGoogleSheet(spreadsheet_id, "TEAM!A1", teamsValues); - await export_service.writeToGoogleSheet(spreadsheet_id, "PERMANENCES!A1", permanenceValues); - await export_service.writeToGoogleSheet(spreadsheet_id, "SHOTGUN!A1", shotgunValues); - - - Ok(res, { msg: "Export réalisé avec succès !" }); - - } catch (error) { - console.error(error); - Error(res, { msg: "Erreur lors de l'export vers Google Sheets" }); - } -}; diff --git a/backend/src/controllers/im_export.controller.ts b/backend/src/controllers/im_export.controller.ts new file mode 100644 index 0000000..a220073 --- /dev/null +++ b/backend/src/controllers/im_export.controller.ts @@ -0,0 +1,168 @@ +import { Request, Response } from "express"; +import * as export_service from "../services/im_export.service"; +import * as user_service from '../services/user.service'; +import * as team_service from "../services/team.service"; +import * as permanence_service from "../services/permanence.service"; +import * as event_service from "../services/event.service"; +import { spreadsheet_id } from "../utils/secret"; +import { Ok, Error } from "../utils/responses"; +import path from "path"; +import fs from "fs"; + +export const exportAllDataToSheets = async (req: Request, res: Response) => { + try { + // 1. Récupération depuis la DB + const userList = await user_service.getUsersAll(); + const teamList = await team_service.getTeamsAll(); + const permanenceList = await permanence_service.getAllPermanencesWithUsers(); + const shotgunList = await event_service.getAllTeamShotguns(); + + + // 2. Mapping -> format pour Google Sheets (array de array) + const usersValues = [ + ["ID", "Prénom", "Nom", "Email", "Branche", "Permission", "Majeur", "Contact","Discord", "Team", "Faction"], + ...userList.map(u => [ + u.id ?? 0, + u.first_name ?? "No first name", + u.last_name ?? "No last name", + u.email ?? "No email", + u.branch ?? "No branch", + u.permission ?? "No permissions", + u.majeur ?? "Pas de données", + u.contact ?? "No contact", + u.discord_id ?? "No discord ID", + u.teamName ?? "No Team", + u.factionName ?? "No faction" + ]) + ]; + + const teamsValues = [ + ["ID", "Nom", "Type", "Faction"], + ...teamList.map(t => [ + t.id, + t.name ?? "No name", + t.type ?? "No type", + t.teamFaction?.name ?? "No faction" + ]) + ]; + +const permanenceValues = [ + [ + "ID", + "Nom", + "Début", + "Fin", + "Lieu", + "Responsables", + "Inscrits (noms)", + "Inscrits (emails)", + "Présents", + "Absents" + ], + ...permanenceList.map((p) => { + const respoNames = p.respo ? p.respo.firstName + " " + p.respo.lastName : "Aucun"; + const userNames = p.users?.map((u) => `${u.first_name} ${u.last_name}`)?.join(" ; ") || "Aucun inscrit"; + const userEmails = p.users?.map((u) => u.email)?.join(" ; ") || "Aucun inscrit"; + + const claimedUsers = p.users?.filter((u) => u.claimed)?.map((u) => `${u.first_name} ${u.last_name}`)?.join(" ; ") || "Aucun"; + const unclaimedUsers = p.users?.filter((u) => !u.claimed)?.map((u) => `${u.first_name} ${u.last_name}`)?.join(" ; ") || "Aucun"; + + return [ + p.id, + p.name ?? "Sans nom", + p.start_at ? new Date(p.start_at).toLocaleString("fr-FR") : "N/A", + p.end_at ? new Date(p.end_at).toLocaleString("fr-FR") : "N/A", + p.location ?? "Sans lieu", + respoNames, + userNames, + userEmails, + claimedUsers, + unclaimedUsers + ]; + }) +]; + + + const shotgunValues = [ + ["ID", "Nom de l'équipe", "Type", "Horodatage"], + ...shotgunList.map(s => [ + s.id, + s.teamName ?? "No name", + s.teamType ?? "No type", + s.timestamp?.toISOString() ?? "No timestamp" + ]) + ]; + // 3. Envoi vers les feuilles + await export_service.writeToGoogleSheet(spreadsheet_id, "USER!A1", usersValues); + await export_service.writeToGoogleSheet(spreadsheet_id, "TEAM!A1", teamsValues); + await export_service.writeToGoogleSheet(spreadsheet_id, "PERMANENCES!A1", permanenceValues); + await export_service.writeToGoogleSheet(spreadsheet_id, "SHOTGUN!A1", shotgunValues); + + + Ok(res, { msg: "Export réalisé avec succès !" }); + + } catch (error) { + console.error(error); + Error(res, { msg: "Erreur lors de l'export vers Google Sheets" }); + } +}; + + +export const updateFoodMenu = async (req: Request, res: Response) => { + + const file = req.file; + + try { + + // Supprimer l'ancien Menu si un nouveau est uploadé + if (file) { + const targetDir = path.join(__dirname, "../../foodmenu"); + + if (fs.existsSync(targetDir)) { + fs.rmSync(targetDir, { recursive: true, force: true }); + fs.mkdirSync(targetDir); + } + } + + Ok(res, { msg: "Menu mis à jour avec succès" }); + return; + } catch (err) { + console.error(err); + Error(res, { msg: "Erreur lors de la mise à jour du Menu" }); + } +}; + +export const updatePlannings = async (req: Request, res: Response) => { + + const file = req.file; + + try { + + // Supprimer l'ancien Planning si un nouveau est uploadé + if (file) { + const targetDir = path.join(__dirname, "../../plannings"); + + if (fs.existsSync(targetDir)) { + fs.rmSync(targetDir, { recursive: true, force: true }); + fs.mkdirSync(targetDir); + } + } + + Ok(res, { msg: "Planning mis à jour avec succès" }); + return; + } catch (err) { + console.error(err); + Error(res, { msg: "Erreur lors de la mise à jour du Planning" }); + } +}; + + +export const exportUsersCSV = async (req: Request, res: Response) => { + try { + const filePath = await export_service.exportUsersToCSV(); + Ok(res, {msg : 'CSV des bus généré'}); + } catch (error) { + console.error(error); + Error(res, { msg: "Erreur lors de l'export CSV" }); + } +}; \ No newline at end of file diff --git a/backend/src/controllers/permanence.controller.ts b/backend/src/controllers/permanence.controller.ts index f1479f7..87f5336 100644 --- a/backend/src/controllers/permanence.controller.ts +++ b/backend/src/controllers/permanence.controller.ts @@ -24,9 +24,9 @@ const validatePermanenceData = (start_at: string, end_at: string) => { // ➕ Créer une permanence export const createPermanence = async (req: Request, res: Response) => { - const { name, description, location, start_at, end_at, capacity } = req.body; + const { name, description, location, start_at, end_at, capacity, difficulty, respoId } = req.body; - if (!name || !location || !start_at || !end_at || !capacity) { + if (!name || !location || !start_at || !end_at || !capacity || !difficulty) { Error(res, { msg: "Tous les champs sont requis" }); return; } @@ -44,7 +44,9 @@ export const createPermanence = async (req: Request, res: Response) => { location, new Date(start_at), new Date(end_at), - Number(capacity) + Number(capacity), + Number(difficulty), + Number(respoId), ); Ok(res, { msg: "Permanence créée avec succès" }); return; @@ -56,9 +58,8 @@ export const createPermanence = async (req: Request, res: Response) => { export const updatePermanence = async (req: Request, res: Response) => { - const { permId, name, description, location, start_at, end_at, capacity } = req.body; - - if (!name || !location || !start_at || !end_at || !capacity) { + const { permId, name, description, location, start_at, end_at, capacity, difficulty, respoId } = req.body; + if (!name || !location || !start_at || !end_at || !capacity || !difficulty) { Error(res, { msg: "Tous les champs sont requis" }); return; } @@ -77,7 +78,9 @@ export const updatePermanence = async (req: Request, res: Response) => { location, new Date(start_at), new Date(end_at), - Number(capacity) + Number(capacity), + Number(difficulty), + Number(respoId) ); Ok(res, { msg: "Permanence mis à jour avec succès" }); } catch (err) { @@ -314,4 +317,61 @@ export const uploadPermanencesCSV = async (req: MulterRequest, res: Response) => } }; +export const isUserRespo = async (req: Request, res: Response) => { + const { userId } = req.query; + + if (!userId) { + Error(res, { msg: "userId est requis" }); + return; + } + + try { + const isRespo = await permanence_service.isUserRespoOfPermanence( + Number(userId) + ); + Ok(res, { data: isRespo }); + } catch (err) { + console.error(err); + Error(res, { msg: "Erreur lors de la vérification du responsable" }); + } +}; + +export const getRespoPermanencesWithMembers = async (req: Request, res: Response) => { + const respoId = req.user?.userId; + + if (!respoId) { + Error(res, { msg: "respoId est requis" }); + return; + } + + try { + const data = await permanence_service.getPermanenceDetailsForRespo(Number(respoId)); + Ok(res, { data }); + } catch (err) { + console.error(err); + Error(res, { msg: "Erreur lors de la récupération des permanences du responsable" }); + } +}; + +export const claimMember = async (req: Request, res: Response) => { + const { userId, permId, claimed } = req.body; + + if (userId === undefined || permId === undefined || claimed === undefined) { + Error(res, { msg: "userId, permId et claimed sont requis" }); + return; + } + + try { + await permanence_service.claimMember(Number(userId), Number(permId), Boolean(claimed)); + Ok(res, { + msg: `Statut mis à jour avec succès (claimed = ${claimed})`, + }); + } catch (err) { + console.error(err); + Error(res, { msg: "Erreur lors de la mise à jour du statut du membre" }); + } +}; + + + diff --git a/backend/src/controllers/team.controller.ts b/backend/src/controllers/team.controller.ts index 9adcb3c..06e8064 100644 --- a/backend/src/controllers/team.controller.ts +++ b/backend/src/controllers/team.controller.ts @@ -11,7 +11,7 @@ export const createNewTeam = async (req: Request, res: Response) => { try { - if(!teamName){ + if (!teamName) { Error(res, { msg: "Il n'y a pas de nom d'équipe" }); return; } @@ -20,11 +20,11 @@ export const createNewTeam = async (req: Request, res: Response) => { Error(res, { msg: "L'enregistrement d'équipe est fermé." }); return; } - if(members.length < 4){ + if (members.length < 4) { Error(res, { msg: "Il n'y a pas assez de membre dans l'équipe." }); return; } - if(members.length > 5){ + if (members.length > 5) { Error(res, { msg: "Il y a trop de membre dans l'équipe." }); return; } @@ -52,8 +52,8 @@ export const createNewTeamLight = async (req: Request, res: Response) => { const { teamName, factionId } = req.body; try { - const newTeamLigth = await team_service.createTeamLight(teamName,factionId); - Ok(res, {msg: "Equipe créée !"}); + const newTeamLigth = await team_service.createTeamLight(teamName, factionId); + Ok(res, { msg: "Equipe créée !" }); } catch (error) { Error(res, { msg: "Erreur lors de la création de l'équipe." }); @@ -92,7 +92,7 @@ export const modifyTeam = async (req: Request, res: Response) => { Error(res, { msg: "teamID est requis pour la mise à jour." }); } - const updatedTeam = await team_service.modifyTeam(teamID, teamMembers, factionID, teamName, type ); + const updatedTeam = await team_service.modifyTeam(teamID, teamMembers, factionID, teamName, type); Ok(res, { data: updatedTeam }); } catch (error) { @@ -103,16 +103,16 @@ export const modifyTeam = async (req: Request, res: Response) => { export const getTeamUsers = async (req: Request, res: Response) => { - const {teamId} = req.query; + const { teamId } = req.query; try { const teamUsers = await team_service.getTeamUsers(teamId); - Ok(res,{ data: teamUsers }); + Ok(res, { data: teamUsers }); return; - } catch (error) { + } catch (error) { console.error(error); - Error(res,{ msg: "Erreur interne lors de la récupération des utilisateurs avec leurs rôles." }); + Error(res, { msg: "Erreur interne lors de la récupération des utilisateurs avec leurs rôles." }); return; - + } } @@ -121,28 +121,28 @@ export const getAllTeamsWithUsers = async (req: Request, res: Response) => { try { const teamUsers = await team_service.getAllTeamsWithUsers(); - Ok(res,{ data: teamUsers }); + Ok(res, { data: teamUsers }); return; - } catch (error) { + } catch (error) { console.error(error); - Error(res,{ msg: "Erreur interne lors de la récupération des utilisateurs avec leurs rôles." }); + Error(res, { msg: "Erreur interne lors de la récupération des utilisateurs avec leurs rôles." }); return; - + } } export const getTeamFaction = async (req: Request, res: Response) => { - const {teamId} = req.query; + const { teamId } = req.query; try { const factionId = await team_service.getTeamFaction(teamId); const teamFaction = await faction_service.getFaction(factionId); - Ok(res,{ data: teamFaction }); + Ok(res, { data: teamFaction }); return; } catch (error) { console.error(error); - Error(res,{ msg: "Erreur interne lors de la récupération des utilisateurs avec leurs rôles." }); + Error(res, { msg: "Erreur interne lors de la récupération des utilisateurs avec leurs rôles." }); return; } @@ -151,15 +151,15 @@ export const getTeamFaction = async (req: Request, res: Response) => { export const deleteTeam = async (req: Request, res: Response) => { try { - const { teamID } = req.query; // Assumes the teamID is passed as a parameter - - if (!teamID) { - Error(res, { msg: "teamID est requis." }); - } - + const { teamID } = req.query; // Assumes the teamID is passed as a parameter + + if (!teamID) { + Error(res, { msg: "teamID est requis." }); + } + const deletedTeam = await team_service.deleteTeam(Number(teamID)); Ok(res, { msg: "Équipe supprimée avec succès.", data: deletedTeam }); - + } catch (error) { console.error(error); Error(res, { msg: "Erreur lors de la suppression de l'équipe." }); @@ -168,86 +168,88 @@ export const deleteTeam = async (req: Request, res: Response) => { export const teamDistribution = async (req: Request, res: Response) => { try { - + const newStudents = await user_service.getUsersbyPermission("Nouveau"); - const userswithteams = (await team_service.getUsersWithTeam()).map((entry: any) => entry.userId); + const userswithteams = (await team_service.getUsersWithTeam()).map((entry: any) => entry.userId); const teams = await team_service.getTeams(); - // Filtrer les étudiants qui ne sont pas dans la liste RI et qui ne sont pas déjà assignés à une équipe - const filteredStudents = newStudents - .filter((student: any) => student.branch !== "RI") //RI - .filter((student : any) => !userswithteams.includes(student.userId)); + // Filtrer les étudiants qui ne sont pas déjà assignés à une équipe + const filteredStudents = newStudents + // .filter((student: any) => student.branch !== "RI") // A decommenter pour ignorer les RI dans la répartition automatique + .filter((student: any) => !userswithteams.includes(student.userId)); // Filtrer les utilisateurs en fonction de la spécialité const tcStudents = filteredStudents - .filter((student: any) => student.branch === "TC") - .map((student: any) => ({ - id: student.userId, - email: student.email, - branch: student.branch - })); - + .filter((student: any) => student.branch === "TC") + .map((student: any) => ({ + id: student.userId, + email: student.email, + branch: student.branch + })); + const otherStudents = filteredStudents - .filter((student: any) => student.branch !== "TC" && student.branch !== "RI" && student.branch !== "MM") - .map((student: any) => ({ - id: student.userId, - email: student.email, - branch: student.branch - })); + // .filter((student: any) => student.branch !== "TC" && student.branch !== "RI" && student.branch !== "MM") A decommenter pour ignorer les RI dans la répartition automatique + .filter((student: any) => student.branch !== "TC" && student.branch !== "MM") + .map((student: any) => ({ + id: student.userId, + email: student.email, + branch: student.branch + })); const PMOMStudents = filteredStudents - .filter((student: any) => student.branch == "MM") - .map((student: any) => ({ - id: student.userId, - email: student.email, - branch: student.branch - })); - + .filter((student: any) => student.branch == "MM") + .map((student: any) => ({ + id: student.userId, + email: student.email, + branch: student.branch + })); + // Filtrer les équipes en fonction de leur type const tcTeams = teams.filter(team => team.type === "TC"); const PMOMTeams = teams.filter(team => team.type === "MM"); - const otherTeams = teams.filter(team => team.type !== "TC" && team.type !== "RI" && team.type !== "MM"); - + // const otherTeams = teams.filter(team => team.type !== "TC" && team.type !== "RI" && team.type !== "MM"); A decommenter pour ignorer les RI dans la répartition automatique + const otherTeams = teams.filter(team => team.type !== "TC" && team.type !== "MM"); + // Fonction pour assigner les utilisateurs à des équipes équilibrées async function assignUsersToTeams(users: any, teams: any) { - // Calculer la taille actuelle des équipes - const teamSizes = await Promise.all(teams.map(async (team: any) => { - const members = await team_service.getTeamUsers(team.teamId); - return { - teamId: team.teamId, - size: members.length - }; - })); - - // Trier les équipes par taille (ascendant) - teamSizes.sort((a: any, b: any) => a.size - b.size); - - for (const user of users) { - // Assigner l'utilisateur à l'équipe avec le moins de membres - const smallestTeam = teamSizes[0]; - await team_service.addTeamMember(smallestTeam.teamId, user.id); - - // Mettre à jour la taille de l'équipe après l'ajout - smallestTeam.size += 1; - - // Réordonner les équipes pour garder la plus petite en premier + // Calculer la taille actuelle des équipes + const teamSizes = await Promise.all(teams.map(async (team: any) => { + const members = await team_service.getTeamUsers(team.teamId); + return { + teamId: team.teamId, + size: members.length + }; + })); + + // Trier les équipes par taille (ascendant) teamSizes.sort((a: any, b: any) => a.size - b.size); - } + + for (const user of users) { + // Assigner l'utilisateur à l'équipe avec le moins de membres + const smallestTeam = teamSizes[0]; + await team_service.addTeamMember(smallestTeam.teamId, user.id); + + // Mettre à jour la taille de l'équipe après l'ajout + smallestTeam.size += 1; + + // Réordonner les équipes pour garder la plus petite en premier + teamSizes.sort((a: any, b: any) => a.size - b.size); + } } // Assigner les utilisateurs TC aux équipes TC - if(tcStudents && tcTeams){ + if (tcStudents && tcTeams) { await assignUsersToTeams(tcStudents, tcTeams); } - + // Assigner les autres utilisateurs aux équipes non-TC - if(otherStudents && otherTeams){ + if (otherStudents && otherTeams) { await assignUsersToTeams(otherStudents, otherTeams); } //Assigner les utilisateurs MM aux équipes MM - if(PMOMStudents && PMOMTeams){ + if (PMOMStudents && PMOMTeams) { await assignUsersToTeams(PMOMStudents, PMOMTeams); } @@ -257,4 +259,4 @@ export const teamDistribution = async (req: Request, res: Response) => { return } } - + diff --git a/backend/src/controllers/tent.controller.ts b/backend/src/controllers/tent.controller.ts new file mode 100644 index 0000000..b9dfb39 --- /dev/null +++ b/backend/src/controllers/tent.controller.ts @@ -0,0 +1,113 @@ +import { Request, Response } from "express"; +import * as tent_service from "../services/tent.service"; +import { Error, Ok } from "../utils/responses"; +import { sendEmail } from "../services/email.service"; +import { getUserById } from "../services/user.service"; +import { generateEmailHtml } from "./email.controller"; + +export const createTent = async (req: Request, res: Response) => { + const { userId2 } = req.body; + const userId1 = req.user?.userId; // Créateur = utilisateur connecté + + if (!userId1 || !userId2) { + return Error(res, { msg: "Identifiants utilisateurs manquants." }); + } + + try { + await tent_service.createTent(userId1, userId2); + Ok(res, { msg: "Tente réservée avec succès." }); + } catch (err: any) { + Error(res, { msg: err.message || "Erreur lors de la création de la tente." }); + } +}; + +export const cancelTent = async (req: Request, res: Response) => { + + const userId1 = req.user?.userId; + + if (!userId1) { + return Error(res, { msg: "Identifiants utilisateurs manquants." }); + } + + try { + await tent_service.cancelTent(userId1); + Ok(res, { msg: "Tente annulée." }); + } catch (err) { + Error(res, { msg: "Erreur lors de l'annulation." }); + } +}; + +export const getUserTent = async (req: Request, res: Response) => { + const userId = req.user?.userId; + if (!userId) return Error(res, { msg: "Utilisateur non authentifié." }); + + try { + const tent = await tent_service.getTentByUser(userId); + Ok(res, { data: tent }); + } catch (err) { + Error(res, { msg: "Erreur lors de la récupération." }); + } +}; + +export const getAllTentPairs = async (req: Request, res: Response) => { + try { + const tents = await tent_service.getAllTents(); + Ok(res, { data: tents }); + } catch (err) { + Error(res, { msg: "Erreur lors de la récupération des binômes." }); + } +}; + +export const toggleTentConfirmation = async (req: Request, res: Response) => { + + const { userId1, userId2, confirmed } = req.body; + + if (!userId1 || !userId2 || typeof confirmed !== "boolean") { + return Error(res, { msg: "Paramètres manquants ou invalides." }); + } + + try { + // Mise à jour de la tente + await tent_service.toggleTentConfirmation(userId1, userId2, confirmed); + + // Récupération des infos utilisateurs + const user1 = await getUserById(userId1); + const user2 = await getUserById(userId2); + + if (!user1 || !user2) { + return Error(res, { msg: "Impossible de récupérer les utilisateurs." }); + } + + // Génération du contenu HTML + const htmlEmail = generateEmailHtml("templateNotifyTentConfirmation", { + user1: `${user1.firstName} ${user1.lastName}`, + user2: `${user2.firstName} ${user2.lastName}`, + confirmed, + }); + + // Options d’email + const emailOptions = { + from: "integration@utt.fr", + to: [user1.email, user2.email], + subject: confirmed + ? "🎉 Votre tente a été validée !" + : "⛺ Votre tente a été dévalidée", + text: "", // optionnel + html: htmlEmail, + }; + + // Envoi + await sendEmail(emailOptions); + + Ok(res, { + msg: confirmed + ? "Tente validée et email envoyé." + : "Tente dévalidée et email envoyé.", + }); + } catch (err: any) { + console.error(err); + Error(res, { + msg: err.message || "Erreur lors de la mise à jour ou de l'envoi d'email.", + }); + } +}; diff --git a/backend/src/controllers/user.controller.ts b/backend/src/controllers/user.controller.ts index afdc535..6fc783a 100644 --- a/backend/src/controllers/user.controller.ts +++ b/backend/src/controllers/user.controller.ts @@ -5,6 +5,7 @@ import { Request, Response } from "express"; import bcrypt from 'bcryptjs'; import * as randomstring from 'randomstring'; import * as auth_service from "../services/auth.service" +import { noSyncEmails } from '../utils/no_sync_list'; export const getUsersAdmin = async (req: Request, res: Response) => { try { @@ -53,9 +54,9 @@ export const syncNewstudent = async (req: Request, res: Response) => { const token = await SIEP_Utils.getTokenUTTAPI(); const newStudents = await SIEP_Utils.getNewStudentsFromUTTAPI_NOPAGE(token, date); - //const newStudentfiltered = newStudents.filter((student : any) => !noSyncEmails.includes(student.email)); + const newStudentfiltered = newStudents.filter((student : any) => !noSyncEmails.includes(student.email));//Nouveau à ne pas sync (Démissionnaires, etc) - for (const element of newStudents) { + for (const element of newStudentfiltered) { let userInDb = await user_service.getUserByEmail(element.email.toLowerCase()); if(userInDb === undefined){ @@ -129,6 +130,3 @@ export const adminDeleteUser = async (req: Request, res: Response) => { Error(res, { msg: "Erreur lors de la suppression de l'utilisateur." }); } }; - - - diff --git a/backend/src/database/db.ts b/backend/src/database/db.ts index 2efdac7..5d63c0b 100644 --- a/backend/src/database/db.ts +++ b/backend/src/database/db.ts @@ -3,24 +3,46 @@ import { Client } from "pg"; import { postgres_user, postgres_db, postgres_host, postgres_password, postgres_port } from '../utils/secret'; // ✅ Import de tous tes schémas ici -import * as user from '../schemas/Basic/user.schema'; -import * as team from '../schemas/Basic/team.schema'; -import * as perm from '../schemas/Basic/permanence.schema'; -import * as event from '../schemas/Basic/event.schema'; -import * as faction from '../schemas/Basic/faction.schema'; -import * as role from '../schemas/Basic/role.schema'; -import * as challenge from '../schemas/Basic/challenge.schema'; -import * as permanence from '../schemas/Basic/permanence.schema'; - -import * as userTeam from '../schemas/Relational/userteams.schema'; -import * as teamFaction from '../schemas/Relational/teamfaction.schema'; -import * as teamShotgun from '../schemas/Relational/teamshotgun.schema'; -import * as userPermanence from '../schemas/Relational/userpermanences.schema'; -import * as userRole from '../schemas/Relational/userroles.schema'; -import * as challengValidation from '../schemas/Relational/challengevalidation.schema'; -import * as busattribution from "../schemas/Relational/busattribution.schema"; -import * as registration from "../schemas/Relational/registration.schema"; - +import * as user from '../schemas/Basic/user.schema'; +import * as team from '../schemas/Basic/team.schema'; +import * as perm from '../schemas/Basic/permanence.schema'; +import * as event from '../schemas/Basic/event.schema'; +import * as faction from '../schemas/Basic/faction.schema'; +import * as role from '../schemas/Basic/role.schema'; +import * as challenge from '../schemas/Basic/challenge.schema'; +import * as permanence from '../schemas/Basic/permanence.schema'; +import * as userTeam from '../schemas/Relational/userteams.schema'; +import * as teamFaction from '../schemas/Relational/teamfaction.schema'; +import * as teamShotgun from '../schemas/Relational/teamshotgun.schema'; +import * as userPermanence from '../schemas/Relational/userpermanences.schema'; +import * as userRole from '../schemas/Relational/userroles.schema'; +import * as challengValidation from '../schemas/Relational/challengevalidation.schema'; +import * as busattribution from "../schemas/Relational/busattribution.schema"; +import * as registration from "../schemas/Relational/registration.schema"; +import * as tent from "../schemas/Relational/usertent.schema"; +import * as rolepoints from "../schemas/Relational/rolepoints.schema"; + + +const schema = { + ...user, + ...team, + ...perm, + ...event, + ...faction, + ...role, + ...challenge, + ...permanence, + ...userTeam, + ...teamFaction, + ...teamShotgun, + ...userPermanence, + ...userRole, + ...challengValidation, + ...busattribution, + ...registration, + ...tent, + ...rolepoints +}; const client = new Client({ connectionString: `postgresql://${postgres_user}:${postgres_password}@${postgres_host}:${postgres_port}/${postgres_db}`, @@ -28,25 +50,4 @@ const client = new Client({ client.connect(); -export const db = drizzle(client, { - schema: { - ...user, - ...team, - ...event, - ...faction, - ...role, - ...perm, - ...challenge, - ...permanence, - - ...userTeam, - ...teamFaction, - ...teamShotgun, - ...userPermanence, - ...userRole, - ...challengValidation, - ...busattribution, - ...registration - - }, -}); +export const db = drizzle(client, {schema: schema}); diff --git a/backend/src/database/initdb/initevent.ts b/backend/src/database/initdb/initevent.ts index 96acc77..46164e8 100644 --- a/backend/src/database/initdb/initevent.ts +++ b/backend/src/database/initdb/initevent.ts @@ -6,6 +6,12 @@ export const initEvent = async () => { // Si il n'y a pas de ligne existante, insérer une nouvelle ligne if (existingEvent.length === 0) { - await db.insert(eventSchema).values({ pre_registration_open: false, shotgun_open: false, sdi_open: false, wei_open: false, food_open : false }).onConflictDoNothing(); + await db.insert(eventSchema).values({ + pre_registration_open: false, + shotgun_open: false, + sdi_open: false, + wei_open: false, + food_open : false, + chall_open : false }).onConflictDoNothing(); } }; \ No newline at end of file diff --git a/backend/src/database/initdb/initrole.ts b/backend/src/database/initdb/initrole.ts index 3bcdb7c..8c92ec4 100644 --- a/backend/src/database/initdb/initrole.ts +++ b/backend/src/database/initdb/initrole.ts @@ -11,6 +11,7 @@ const roles = [ { name: "Argentique", description: "Couvrir les événements de l’intégration, prendre des photos" }, { name: "Bouffe", description: "Prévoir, organiser et coordonner tous les repas de l’inté. La bouffe c’est sacré !" }, { name: "Bar", description: "Prévoir, organiser et coordonner toutes les boissons de l’inté !" }, + { name: "Bénévole", description: "Deviens bénévole et participe à différentes activités de l’inté !" }, { name: "Cahier de vacances", description: "Élaborer le futur cahier de vacances des nouveaux avec des petits exercices et blagues." }, { name: "Chasse au trésor", description: "Elaborer une chasse au trésor dans toute la capitale Troyenne." }, { name: "Communication", description: "Préparer et gérer toute la communication de l’intégration" }, diff --git a/backend/src/database/migrations/0017_melted_meggan.sql b/backend/src/database/migrations/0017_melted_meggan.sql new file mode 100644 index 0000000..06b4bc5 --- /dev/null +++ b/backend/src/database/migrations/0017_melted_meggan.sql @@ -0,0 +1 @@ +ALTER TABLE "events" ADD COLUMN "food_open" boolean DEFAULT false; \ No newline at end of file diff --git a/backend/src/database/migrations/0018_puzzling_arachne.sql b/backend/src/database/migrations/0018_puzzling_arachne.sql new file mode 100644 index 0000000..c366235 --- /dev/null +++ b/backend/src/database/migrations/0018_puzzling_arachne.sql @@ -0,0 +1 @@ +ALTER TABLE "events" ADD COLUMN "chall_open" boolean DEFAULT false; \ No newline at end of file diff --git a/backend/src/database/migrations/0019_complete_moondragon.sql b/backend/src/database/migrations/0019_complete_moondragon.sql new file mode 100644 index 0000000..8301a75 --- /dev/null +++ b/backend/src/database/migrations/0019_complete_moondragon.sql @@ -0,0 +1,2 @@ +ALTER TABLE "permanences" ADD COLUMN "difficulty" integer;--> statement-breakpoint +ALTER TABLE "user_permanences" ADD COLUMN "claimed" boolean DEFAULT false; \ No newline at end of file diff --git a/backend/src/database/migrations/0020_strange_colonel_america.sql b/backend/src/database/migrations/0020_strange_colonel_america.sql new file mode 100644 index 0000000..6551b54 --- /dev/null +++ b/backend/src/database/migrations/0020_strange_colonel_america.sql @@ -0,0 +1,8 @@ +CREATE TABLE "respo_permanences" ( + "user_id" integer, + "permanence_id" integer, + CONSTRAINT "respo_permanences_user_id_permanence_id_pk" PRIMARY KEY("user_id","permanence_id") +); +--> statement-breakpoint +ALTER TABLE "respo_permanences" ADD CONSTRAINT "respo_permanences_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "respo_permanences" ADD CONSTRAINT "respo_permanences_permanence_id_permanences_id_fk" FOREIGN KEY ("permanence_id") REFERENCES "public"."permanences"("id") ON DELETE cascade ON UPDATE no action; \ No newline at end of file diff --git a/backend/src/database/migrations/0021_colossal_madame_web.sql b/backend/src/database/migrations/0021_colossal_madame_web.sql new file mode 100644 index 0000000..123c2df --- /dev/null +++ b/backend/src/database/migrations/0021_colossal_madame_web.sql @@ -0,0 +1,10 @@ +CREATE TABLE "user_tent" ( + "user_id_1" integer, + "user_id_2" integer, + "confirmed" boolean DEFAULT false, + "created_at" timestamp DEFAULT now(), + CONSTRAINT "user_tent_user_id_1_user_id_2_pk" PRIMARY KEY("user_id_1","user_id_2") +); +--> statement-breakpoint +ALTER TABLE "user_tent" ADD CONSTRAINT "user_tent_user_id_1_users_id_fk" FOREIGN KEY ("user_id_1") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "user_tent" ADD CONSTRAINT "user_tent_user_id_2_users_id_fk" FOREIGN KEY ("user_id_2") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; \ No newline at end of file diff --git a/backend/src/database/migrations/meta/0017_snapshot.json b/backend/src/database/migrations/meta/0017_snapshot.json new file mode 100644 index 0000000..2ee6959 --- /dev/null +++ b/backend/src/database/migrations/meta/0017_snapshot.json @@ -0,0 +1,1124 @@ +{ + "id": "81f84527-e2a4-45b5-9ba1-b3cf61c50ccd", + "prevId": "3fddc2ef-4b10-4316-ad1b-2a003214f9ef", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.challenges": { + "name": "challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "challenges_created_by_users_id_fk": { + "name": "challenges_created_by_users_id_fk", + "tableFrom": "challenges", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "pre_registration_open": { + "name": "pre_registration_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "shotgun_open": { + "name": "shotgun_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "sdi_open": { + "name": "sdi_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "wei_open": { + "name": "wei_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_open": { + "name": "food_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.factions": { + "name": "factions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "factions_name_unique": { + "name": "factions_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.news": { + "name": "news", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "target": { + "name": "target", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.permanences": { + "name": "permanences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "end_at": { + "name": "end_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_open": { + "name": "is_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.teams": { + "name": "teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "teams_name_unique": { + "name": "teams_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "majeur": { + "name": "majeur", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contact": { + "name": "contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Nouveau'" + }, + "discord_id": { + "name": "discord_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bus_attribution": { + "name": "bus_attribution", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "bus": { + "name": "bus", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "bus_attribution_user_id_users_id_fk": { + "name": "bus_attribution_user_id_users_id_fk", + "tableFrom": "bus_attribution", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.challenge_validation": { + "name": "challenge_validation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_by_admin_id": { + "name": "validated_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_at": { + "name": "validated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "target_user_id": { + "name": "target_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_team_id": { + "name": "target_team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_faction_id": { + "name": "target_faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "added_by_admin_id": { + "name": "added_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "challenge_validation_challenge_id_challenges_id_fk": { + "name": "challenge_validation_challenge_id_challenges_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "challenges", + "columnsFrom": [ + "challenge_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_validated_by_admin_id_users_id_fk": { + "name": "challenge_validation_validated_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "validated_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_user_id_users_id_fk": { + "name": "challenge_validation_target_user_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_team_id_teams_id_fk": { + "name": "challenge_validation_target_team_id_teams_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "teams", + "columnsFrom": [ + "target_team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_faction_id_factions_id_fk": { + "name": "challenge_validation_target_faction_id_factions_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "factions", + "columnsFrom": [ + "target_faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_added_by_admin_id_users_id_fk": { + "name": "challenge_validation_added_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "added_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.registration_tokens": { + "name": "registration_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "registration_tokens_user_id_users_id_fk": { + "name": "registration_tokens_user_id_users_id_fk", + "tableFrom": "registration_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "registration_tokens_token_unique": { + "name": "registration_tokens_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.role_points": { + "name": "role_points", + "schema": "", + "columns": { + "role_points": { + "name": "role_points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "role_points_role_points_roles_id_fk": { + "name": "role_points_role_points_roles_id_fk", + "tableFrom": "role_points", + "tableTo": "roles", + "columnsFrom": [ + "role_points" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "role_points_role_points_pk": { + "name": "role_points_role_points_pk", + "columns": [ + "role_points" + ] + } + }, + "uniqueConstraints": { + "role_points_role_points_unique": { + "name": "role_points_role_points_unique", + "nullsNotDistinct": false, + "columns": [ + "role_points" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_faction": { + "name": "team_faction", + "schema": "", + "columns": { + "faction_id": { + "name": "faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "team_faction_faction_id_factions_id_fk": { + "name": "team_faction_faction_id_factions_id_fk", + "tableFrom": "team_faction", + "tableTo": "factions", + "columnsFrom": [ + "faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_faction_team_id_teams_id_fk": { + "name": "team_faction_team_id_teams_id_fk", + "tableFrom": "team_faction", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "team_faction_faction_id_team_id_pk": { + "name": "team_faction_faction_id_team_id_pk", + "columns": [ + "faction_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_shotgun": { + "name": "team_shotgun", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "team_shotgun_team_id_teams_id_fk": { + "name": "team_shotgun_team_id_teams_id_fk", + "tableFrom": "team_shotgun", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_permanences": { + "name": "user_permanences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "permanence_id": { + "name": "permanence_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "registered_at": { + "name": "registered_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_permanences_user_id_users_id_fk": { + "name": "user_permanences_user_id_users_id_fk", + "tableFrom": "user_permanences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_permanences_permanence_id_permanences_id_fk": { + "name": "user_permanences_permanence_id_permanences_id_fk", + "tableFrom": "user_permanences", + "tableTo": "permanences", + "columnsFrom": [ + "permanence_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_permanences_user_id_permanence_id_pk": { + "name": "user_permanences_user_id_permanence_id_pk", + "columns": [ + "user_id", + "permanence_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_preferences": { + "name": "user_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_preferences_role_id_roles_id_fk": { + "name": "user_preferences_role_id_roles_id_fk", + "tableFrom": "user_preferences", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_preferences_user_id_role_id_pk": { + "name": "user_preferences_user_id_role_id_pk", + "columns": [ + "user_id", + "role_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_teams": { + "name": "user_teams", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_teams_user_id_users_id_fk": { + "name": "user_teams_user_id_users_id_fk", + "tableFrom": "user_teams", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_teams_team_id_teams_id_fk": { + "name": "user_teams_team_id_teams_id_fk", + "tableFrom": "user_teams", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_teams_user_id_team_id_pk": { + "name": "user_teams_user_id_team_id_pk", + "columns": [ + "user_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/backend/src/database/migrations/meta/0018_snapshot.json b/backend/src/database/migrations/meta/0018_snapshot.json new file mode 100644 index 0000000..f0917ee --- /dev/null +++ b/backend/src/database/migrations/meta/0018_snapshot.json @@ -0,0 +1,1131 @@ +{ + "id": "4858ad67-d3ef-412a-850f-0b486d91795c", + "prevId": "81f84527-e2a4-45b5-9ba1-b3cf61c50ccd", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.challenges": { + "name": "challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "challenges_created_by_users_id_fk": { + "name": "challenges_created_by_users_id_fk", + "tableFrom": "challenges", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "pre_registration_open": { + "name": "pre_registration_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "shotgun_open": { + "name": "shotgun_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "sdi_open": { + "name": "sdi_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "wei_open": { + "name": "wei_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_open": { + "name": "food_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "chall_open": { + "name": "chall_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.factions": { + "name": "factions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "factions_name_unique": { + "name": "factions_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.news": { + "name": "news", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "target": { + "name": "target", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.permanences": { + "name": "permanences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "end_at": { + "name": "end_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_open": { + "name": "is_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.teams": { + "name": "teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "teams_name_unique": { + "name": "teams_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "majeur": { + "name": "majeur", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contact": { + "name": "contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Nouveau'" + }, + "discord_id": { + "name": "discord_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bus_attribution": { + "name": "bus_attribution", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "bus": { + "name": "bus", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "bus_attribution_user_id_users_id_fk": { + "name": "bus_attribution_user_id_users_id_fk", + "tableFrom": "bus_attribution", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.challenge_validation": { + "name": "challenge_validation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_by_admin_id": { + "name": "validated_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_at": { + "name": "validated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "target_user_id": { + "name": "target_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_team_id": { + "name": "target_team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_faction_id": { + "name": "target_faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "added_by_admin_id": { + "name": "added_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "challenge_validation_challenge_id_challenges_id_fk": { + "name": "challenge_validation_challenge_id_challenges_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "challenges", + "columnsFrom": [ + "challenge_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_validated_by_admin_id_users_id_fk": { + "name": "challenge_validation_validated_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "validated_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_user_id_users_id_fk": { + "name": "challenge_validation_target_user_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_team_id_teams_id_fk": { + "name": "challenge_validation_target_team_id_teams_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "teams", + "columnsFrom": [ + "target_team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_faction_id_factions_id_fk": { + "name": "challenge_validation_target_faction_id_factions_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "factions", + "columnsFrom": [ + "target_faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_added_by_admin_id_users_id_fk": { + "name": "challenge_validation_added_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "added_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.registration_tokens": { + "name": "registration_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "registration_tokens_user_id_users_id_fk": { + "name": "registration_tokens_user_id_users_id_fk", + "tableFrom": "registration_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "registration_tokens_token_unique": { + "name": "registration_tokens_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.role_points": { + "name": "role_points", + "schema": "", + "columns": { + "role_points": { + "name": "role_points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "role_points_role_points_roles_id_fk": { + "name": "role_points_role_points_roles_id_fk", + "tableFrom": "role_points", + "tableTo": "roles", + "columnsFrom": [ + "role_points" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "role_points_role_points_pk": { + "name": "role_points_role_points_pk", + "columns": [ + "role_points" + ] + } + }, + "uniqueConstraints": { + "role_points_role_points_unique": { + "name": "role_points_role_points_unique", + "nullsNotDistinct": false, + "columns": [ + "role_points" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_faction": { + "name": "team_faction", + "schema": "", + "columns": { + "faction_id": { + "name": "faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "team_faction_faction_id_factions_id_fk": { + "name": "team_faction_faction_id_factions_id_fk", + "tableFrom": "team_faction", + "tableTo": "factions", + "columnsFrom": [ + "faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_faction_team_id_teams_id_fk": { + "name": "team_faction_team_id_teams_id_fk", + "tableFrom": "team_faction", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "team_faction_faction_id_team_id_pk": { + "name": "team_faction_faction_id_team_id_pk", + "columns": [ + "faction_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_shotgun": { + "name": "team_shotgun", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "team_shotgun_team_id_teams_id_fk": { + "name": "team_shotgun_team_id_teams_id_fk", + "tableFrom": "team_shotgun", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_permanences": { + "name": "user_permanences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "permanence_id": { + "name": "permanence_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "registered_at": { + "name": "registered_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_permanences_user_id_users_id_fk": { + "name": "user_permanences_user_id_users_id_fk", + "tableFrom": "user_permanences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_permanences_permanence_id_permanences_id_fk": { + "name": "user_permanences_permanence_id_permanences_id_fk", + "tableFrom": "user_permanences", + "tableTo": "permanences", + "columnsFrom": [ + "permanence_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_permanences_user_id_permanence_id_pk": { + "name": "user_permanences_user_id_permanence_id_pk", + "columns": [ + "user_id", + "permanence_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_preferences": { + "name": "user_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_preferences_role_id_roles_id_fk": { + "name": "user_preferences_role_id_roles_id_fk", + "tableFrom": "user_preferences", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_preferences_user_id_role_id_pk": { + "name": "user_preferences_user_id_role_id_pk", + "columns": [ + "user_id", + "role_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_teams": { + "name": "user_teams", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_teams_user_id_users_id_fk": { + "name": "user_teams_user_id_users_id_fk", + "tableFrom": "user_teams", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_teams_team_id_teams_id_fk": { + "name": "user_teams_team_id_teams_id_fk", + "tableFrom": "user_teams", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_teams_user_id_team_id_pk": { + "name": "user_teams_user_id_team_id_pk", + "columns": [ + "user_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/backend/src/database/migrations/meta/0019_snapshot.json b/backend/src/database/migrations/meta/0019_snapshot.json new file mode 100644 index 0000000..adbcfb7 --- /dev/null +++ b/backend/src/database/migrations/meta/0019_snapshot.json @@ -0,0 +1,1144 @@ +{ + "id": "e74fe262-0a2d-4bf3-9c11-62d66f3b7aa5", + "prevId": "4858ad67-d3ef-412a-850f-0b486d91795c", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.challenges": { + "name": "challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "challenges_created_by_users_id_fk": { + "name": "challenges_created_by_users_id_fk", + "tableFrom": "challenges", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "pre_registration_open": { + "name": "pre_registration_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "shotgun_open": { + "name": "shotgun_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "sdi_open": { + "name": "sdi_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "wei_open": { + "name": "wei_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_open": { + "name": "food_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "chall_open": { + "name": "chall_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.factions": { + "name": "factions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "factions_name_unique": { + "name": "factions_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.news": { + "name": "news", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "target": { + "name": "target", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.permanences": { + "name": "permanences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "end_at": { + "name": "end_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_open": { + "name": "is_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "difficulty": { + "name": "difficulty", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.teams": { + "name": "teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "teams_name_unique": { + "name": "teams_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "majeur": { + "name": "majeur", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contact": { + "name": "contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Nouveau'" + }, + "discord_id": { + "name": "discord_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bus_attribution": { + "name": "bus_attribution", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "bus": { + "name": "bus", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "bus_attribution_user_id_users_id_fk": { + "name": "bus_attribution_user_id_users_id_fk", + "tableFrom": "bus_attribution", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.challenge_validation": { + "name": "challenge_validation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_by_admin_id": { + "name": "validated_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_at": { + "name": "validated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "target_user_id": { + "name": "target_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_team_id": { + "name": "target_team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_faction_id": { + "name": "target_faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "added_by_admin_id": { + "name": "added_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "challenge_validation_challenge_id_challenges_id_fk": { + "name": "challenge_validation_challenge_id_challenges_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "challenges", + "columnsFrom": [ + "challenge_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_validated_by_admin_id_users_id_fk": { + "name": "challenge_validation_validated_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "validated_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_user_id_users_id_fk": { + "name": "challenge_validation_target_user_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_team_id_teams_id_fk": { + "name": "challenge_validation_target_team_id_teams_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "teams", + "columnsFrom": [ + "target_team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_faction_id_factions_id_fk": { + "name": "challenge_validation_target_faction_id_factions_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "factions", + "columnsFrom": [ + "target_faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_added_by_admin_id_users_id_fk": { + "name": "challenge_validation_added_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "added_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.registration_tokens": { + "name": "registration_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "registration_tokens_user_id_users_id_fk": { + "name": "registration_tokens_user_id_users_id_fk", + "tableFrom": "registration_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "registration_tokens_token_unique": { + "name": "registration_tokens_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.role_points": { + "name": "role_points", + "schema": "", + "columns": { + "role_points": { + "name": "role_points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "role_points_role_points_roles_id_fk": { + "name": "role_points_role_points_roles_id_fk", + "tableFrom": "role_points", + "tableTo": "roles", + "columnsFrom": [ + "role_points" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "role_points_role_points_pk": { + "name": "role_points_role_points_pk", + "columns": [ + "role_points" + ] + } + }, + "uniqueConstraints": { + "role_points_role_points_unique": { + "name": "role_points_role_points_unique", + "nullsNotDistinct": false, + "columns": [ + "role_points" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_faction": { + "name": "team_faction", + "schema": "", + "columns": { + "faction_id": { + "name": "faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "team_faction_faction_id_factions_id_fk": { + "name": "team_faction_faction_id_factions_id_fk", + "tableFrom": "team_faction", + "tableTo": "factions", + "columnsFrom": [ + "faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_faction_team_id_teams_id_fk": { + "name": "team_faction_team_id_teams_id_fk", + "tableFrom": "team_faction", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "team_faction_faction_id_team_id_pk": { + "name": "team_faction_faction_id_team_id_pk", + "columns": [ + "faction_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_shotgun": { + "name": "team_shotgun", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "team_shotgun_team_id_teams_id_fk": { + "name": "team_shotgun_team_id_teams_id_fk", + "tableFrom": "team_shotgun", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_permanences": { + "name": "user_permanences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "permanence_id": { + "name": "permanence_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "registered_at": { + "name": "registered_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "claimed": { + "name": "claimed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_permanences_user_id_users_id_fk": { + "name": "user_permanences_user_id_users_id_fk", + "tableFrom": "user_permanences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_permanences_permanence_id_permanences_id_fk": { + "name": "user_permanences_permanence_id_permanences_id_fk", + "tableFrom": "user_permanences", + "tableTo": "permanences", + "columnsFrom": [ + "permanence_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_permanences_user_id_permanence_id_pk": { + "name": "user_permanences_user_id_permanence_id_pk", + "columns": [ + "user_id", + "permanence_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_preferences": { + "name": "user_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_preferences_role_id_roles_id_fk": { + "name": "user_preferences_role_id_roles_id_fk", + "tableFrom": "user_preferences", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_preferences_user_id_role_id_pk": { + "name": "user_preferences_user_id_role_id_pk", + "columns": [ + "user_id", + "role_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_teams": { + "name": "user_teams", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_teams_user_id_users_id_fk": { + "name": "user_teams_user_id_users_id_fk", + "tableFrom": "user_teams", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_teams_team_id_teams_id_fk": { + "name": "user_teams_team_id_teams_id_fk", + "tableFrom": "user_teams", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_teams_user_id_team_id_pk": { + "name": "user_teams_user_id_team_id_pk", + "columns": [ + "user_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/backend/src/database/migrations/meta/0020_snapshot.json b/backend/src/database/migrations/meta/0020_snapshot.json new file mode 100644 index 0000000..1fe21cb --- /dev/null +++ b/backend/src/database/migrations/meta/0020_snapshot.json @@ -0,0 +1,1204 @@ +{ + "id": "5570d860-0dbd-48fe-9fb5-5314cdb1a473", + "prevId": "e74fe262-0a2d-4bf3-9c11-62d66f3b7aa5", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.challenges": { + "name": "challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "challenges_created_by_users_id_fk": { + "name": "challenges_created_by_users_id_fk", + "tableFrom": "challenges", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "pre_registration_open": { + "name": "pre_registration_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "shotgun_open": { + "name": "shotgun_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "sdi_open": { + "name": "sdi_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "wei_open": { + "name": "wei_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_open": { + "name": "food_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "chall_open": { + "name": "chall_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.factions": { + "name": "factions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "factions_name_unique": { + "name": "factions_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.news": { + "name": "news", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "target": { + "name": "target", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.permanences": { + "name": "permanences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "end_at": { + "name": "end_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_open": { + "name": "is_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "difficulty": { + "name": "difficulty", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.teams": { + "name": "teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "teams_name_unique": { + "name": "teams_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "majeur": { + "name": "majeur", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contact": { + "name": "contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Nouveau'" + }, + "discord_id": { + "name": "discord_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bus_attribution": { + "name": "bus_attribution", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "bus": { + "name": "bus", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "bus_attribution_user_id_users_id_fk": { + "name": "bus_attribution_user_id_users_id_fk", + "tableFrom": "bus_attribution", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.challenge_validation": { + "name": "challenge_validation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_by_admin_id": { + "name": "validated_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_at": { + "name": "validated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "target_user_id": { + "name": "target_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_team_id": { + "name": "target_team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_faction_id": { + "name": "target_faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "added_by_admin_id": { + "name": "added_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "challenge_validation_challenge_id_challenges_id_fk": { + "name": "challenge_validation_challenge_id_challenges_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "challenges", + "columnsFrom": [ + "challenge_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_validated_by_admin_id_users_id_fk": { + "name": "challenge_validation_validated_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "validated_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_user_id_users_id_fk": { + "name": "challenge_validation_target_user_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_team_id_teams_id_fk": { + "name": "challenge_validation_target_team_id_teams_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "teams", + "columnsFrom": [ + "target_team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_faction_id_factions_id_fk": { + "name": "challenge_validation_target_faction_id_factions_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "factions", + "columnsFrom": [ + "target_faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_added_by_admin_id_users_id_fk": { + "name": "challenge_validation_added_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "added_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.registration_tokens": { + "name": "registration_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "registration_tokens_user_id_users_id_fk": { + "name": "registration_tokens_user_id_users_id_fk", + "tableFrom": "registration_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "registration_tokens_token_unique": { + "name": "registration_tokens_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.role_points": { + "name": "role_points", + "schema": "", + "columns": { + "role_points": { + "name": "role_points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "role_points_role_points_roles_id_fk": { + "name": "role_points_role_points_roles_id_fk", + "tableFrom": "role_points", + "tableTo": "roles", + "columnsFrom": [ + "role_points" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "role_points_role_points_pk": { + "name": "role_points_role_points_pk", + "columns": [ + "role_points" + ] + } + }, + "uniqueConstraints": { + "role_points_role_points_unique": { + "name": "role_points_role_points_unique", + "nullsNotDistinct": false, + "columns": [ + "role_points" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_faction": { + "name": "team_faction", + "schema": "", + "columns": { + "faction_id": { + "name": "faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "team_faction_faction_id_factions_id_fk": { + "name": "team_faction_faction_id_factions_id_fk", + "tableFrom": "team_faction", + "tableTo": "factions", + "columnsFrom": [ + "faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_faction_team_id_teams_id_fk": { + "name": "team_faction_team_id_teams_id_fk", + "tableFrom": "team_faction", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "team_faction_faction_id_team_id_pk": { + "name": "team_faction_faction_id_team_id_pk", + "columns": [ + "faction_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_shotgun": { + "name": "team_shotgun", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "team_shotgun_team_id_teams_id_fk": { + "name": "team_shotgun_team_id_teams_id_fk", + "tableFrom": "team_shotgun", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.respo_permanences": { + "name": "respo_permanences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "permanence_id": { + "name": "permanence_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "respo_permanences_user_id_users_id_fk": { + "name": "respo_permanences_user_id_users_id_fk", + "tableFrom": "respo_permanences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "respo_permanences_permanence_id_permanences_id_fk": { + "name": "respo_permanences_permanence_id_permanences_id_fk", + "tableFrom": "respo_permanences", + "tableTo": "permanences", + "columnsFrom": [ + "permanence_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "respo_permanences_user_id_permanence_id_pk": { + "name": "respo_permanences_user_id_permanence_id_pk", + "columns": [ + "user_id", + "permanence_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_permanences": { + "name": "user_permanences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "permanence_id": { + "name": "permanence_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "registered_at": { + "name": "registered_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "claimed": { + "name": "claimed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_permanences_user_id_users_id_fk": { + "name": "user_permanences_user_id_users_id_fk", + "tableFrom": "user_permanences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_permanences_permanence_id_permanences_id_fk": { + "name": "user_permanences_permanence_id_permanences_id_fk", + "tableFrom": "user_permanences", + "tableTo": "permanences", + "columnsFrom": [ + "permanence_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_permanences_user_id_permanence_id_pk": { + "name": "user_permanences_user_id_permanence_id_pk", + "columns": [ + "user_id", + "permanence_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_preferences": { + "name": "user_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_preferences_role_id_roles_id_fk": { + "name": "user_preferences_role_id_roles_id_fk", + "tableFrom": "user_preferences", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_preferences_user_id_role_id_pk": { + "name": "user_preferences_user_id_role_id_pk", + "columns": [ + "user_id", + "role_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_teams": { + "name": "user_teams", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_teams_user_id_users_id_fk": { + "name": "user_teams_user_id_users_id_fk", + "tableFrom": "user_teams", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_teams_team_id_teams_id_fk": { + "name": "user_teams_team_id_teams_id_fk", + "tableFrom": "user_teams", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_teams_user_id_team_id_pk": { + "name": "user_teams_user_id_team_id_pk", + "columns": [ + "user_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/backend/src/database/migrations/meta/0021_snapshot.json b/backend/src/database/migrations/meta/0021_snapshot.json new file mode 100644 index 0000000..546fbbb --- /dev/null +++ b/backend/src/database/migrations/meta/0021_snapshot.json @@ -0,0 +1,1278 @@ +{ + "id": "9a19155e-ddd0-492f-a2df-0bb9ef0d9879", + "prevId": "5570d860-0dbd-48fe-9fb5-5314cdb1a473", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.challenges": { + "name": "challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "challenges_created_by_users_id_fk": { + "name": "challenges_created_by_users_id_fk", + "tableFrom": "challenges", + "tableTo": "users", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "pre_registration_open": { + "name": "pre_registration_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "shotgun_open": { + "name": "shotgun_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "sdi_open": { + "name": "sdi_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "wei_open": { + "name": "wei_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "food_open": { + "name": "food_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "chall_open": { + "name": "chall_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.factions": { + "name": "factions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "factions_name_unique": { + "name": "factions_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.news": { + "name": "news", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "target": { + "name": "target", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.permanences": { + "name": "permanences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "end_at": { + "name": "end_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_open": { + "name": "is_open", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "difficulty": { + "name": "difficulty", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "roles_name_unique": { + "name": "roles_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.teams": { + "name": "teams", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "teams_name_unique": { + "name": "teams_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "majeur": { + "name": "majeur", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "branch": { + "name": "branch", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contact": { + "name": "contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Nouveau'" + }, + "discord_id": { + "name": "discord_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bus_attribution": { + "name": "bus_attribution", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "bus": { + "name": "bus", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "bus_attribution_user_id_users_id_fk": { + "name": "bus_attribution_user_id_users_id_fk", + "tableFrom": "bus_attribution", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.challenge_validation": { + "name": "challenge_validation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "challenge_id": { + "name": "challenge_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_by_admin_id": { + "name": "validated_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "validated_at": { + "name": "validated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "target_user_id": { + "name": "target_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_team_id": { + "name": "target_team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_faction_id": { + "name": "target_faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "added_by_admin_id": { + "name": "added_by_admin_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "challenge_validation_challenge_id_challenges_id_fk": { + "name": "challenge_validation_challenge_id_challenges_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "challenges", + "columnsFrom": [ + "challenge_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_validated_by_admin_id_users_id_fk": { + "name": "challenge_validation_validated_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "validated_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_user_id_users_id_fk": { + "name": "challenge_validation_target_user_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "target_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_team_id_teams_id_fk": { + "name": "challenge_validation_target_team_id_teams_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "teams", + "columnsFrom": [ + "target_team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_target_faction_id_factions_id_fk": { + "name": "challenge_validation_target_faction_id_factions_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "factions", + "columnsFrom": [ + "target_faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "challenge_validation_added_by_admin_id_users_id_fk": { + "name": "challenge_validation_added_by_admin_id_users_id_fk", + "tableFrom": "challenge_validation", + "tableTo": "users", + "columnsFrom": [ + "added_by_admin_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.registration_tokens": { + "name": "registration_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "registration_tokens_user_id_users_id_fk": { + "name": "registration_tokens_user_id_users_id_fk", + "tableFrom": "registration_tokens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "registration_tokens_token_unique": { + "name": "registration_tokens_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.role_points": { + "name": "role_points", + "schema": "", + "columns": { + "role_points": { + "name": "role_points", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "role_points_role_points_roles_id_fk": { + "name": "role_points_role_points_roles_id_fk", + "tableFrom": "role_points", + "tableTo": "roles", + "columnsFrom": [ + "role_points" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "role_points_role_points_pk": { + "name": "role_points_role_points_pk", + "columns": [ + "role_points" + ] + } + }, + "uniqueConstraints": { + "role_points_role_points_unique": { + "name": "role_points_role_points_unique", + "nullsNotDistinct": false, + "columns": [ + "role_points" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_faction": { + "name": "team_faction", + "schema": "", + "columns": { + "faction_id": { + "name": "faction_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "team_faction_faction_id_factions_id_fk": { + "name": "team_faction_faction_id_factions_id_fk", + "tableFrom": "team_faction", + "tableTo": "factions", + "columnsFrom": [ + "faction_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_faction_team_id_teams_id_fk": { + "name": "team_faction_team_id_teams_id_fk", + "tableFrom": "team_faction", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "team_faction_faction_id_team_id_pk": { + "name": "team_faction_faction_id_team_id_pk", + "columns": [ + "faction_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.team_shotgun": { + "name": "team_shotgun", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "team_shotgun_team_id_teams_id_fk": { + "name": "team_shotgun_team_id_teams_id_fk", + "tableFrom": "team_shotgun", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.respo_permanences": { + "name": "respo_permanences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "permanence_id": { + "name": "permanence_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "respo_permanences_user_id_users_id_fk": { + "name": "respo_permanences_user_id_users_id_fk", + "tableFrom": "respo_permanences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "respo_permanences_permanence_id_permanences_id_fk": { + "name": "respo_permanences_permanence_id_permanences_id_fk", + "tableFrom": "respo_permanences", + "tableTo": "permanences", + "columnsFrom": [ + "permanence_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "respo_permanences_user_id_permanence_id_pk": { + "name": "respo_permanences_user_id_permanence_id_pk", + "columns": [ + "user_id", + "permanence_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_permanences": { + "name": "user_permanences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "permanence_id": { + "name": "permanence_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "registered_at": { + "name": "registered_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "claimed": { + "name": "claimed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_permanences_user_id_users_id_fk": { + "name": "user_permanences_user_id_users_id_fk", + "tableFrom": "user_permanences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_permanences_permanence_id_permanences_id_fk": { + "name": "user_permanences_permanence_id_permanences_id_fk", + "tableFrom": "user_permanences", + "tableTo": "permanences", + "columnsFrom": [ + "permanence_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_permanences_user_id_permanence_id_pk": { + "name": "user_permanences_user_id_permanence_id_pk", + "columns": [ + "user_id", + "permanence_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_preferences": { + "name": "user_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_preferences_user_id_users_id_fk": { + "name": "user_preferences_user_id_users_id_fk", + "tableFrom": "user_preferences", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_preferences_role_id_roles_id_fk": { + "name": "user_preferences_role_id_roles_id_fk", + "tableFrom": "user_preferences", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_preferences_user_id_role_id_pk": { + "name": "user_preferences_user_id_role_id_pk", + "columns": [ + "user_id", + "role_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_roles_user_id_users_id_fk": { + "name": "user_roles_user_id_users_id_fk", + "tableFrom": "user_roles", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_roles_role_id_roles_id_fk": { + "name": "user_roles_role_id_roles_id_fk", + "tableFrom": "user_roles", + "tableTo": "roles", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_teams": { + "name": "user_teams", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "team_id": { + "name": "team_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_teams_user_id_users_id_fk": { + "name": "user_teams_user_id_users_id_fk", + "tableFrom": "user_teams", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_teams_team_id_teams_id_fk": { + "name": "user_teams_team_id_teams_id_fk", + "tableFrom": "user_teams", + "tableTo": "teams", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_teams_user_id_team_id_pk": { + "name": "user_teams_user_id_team_id_pk", + "columns": [ + "user_id", + "team_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_tent": { + "name": "user_tent", + "schema": "", + "columns": { + "user_id_1": { + "name": "user_id_1", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "user_id_2": { + "name": "user_id_2", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "confirmed": { + "name": "confirmed", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_tent_user_id_1_users_id_fk": { + "name": "user_tent_user_id_1_users_id_fk", + "tableFrom": "user_tent", + "tableTo": "users", + "columnsFrom": [ + "user_id_1" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_tent_user_id_2_users_id_fk": { + "name": "user_tent_user_id_2_users_id_fk", + "tableFrom": "user_tent", + "tableTo": "users", + "columnsFrom": [ + "user_id_2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_tent_user_id_1_user_id_2_pk": { + "name": "user_tent_user_id_1_user_id_2_pk", + "columns": [ + "user_id_1", + "user_id_2" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/backend/src/database/migrations/meta/_journal.json b/backend/src/database/migrations/meta/_journal.json index fc20490..71ffc61 100644 --- a/backend/src/database/migrations/meta/_journal.json +++ b/backend/src/database/migrations/meta/_journal.json @@ -120,6 +120,41 @@ "when": 1754903172897, "tag": "0016_sudden_ultimatum", "breakpoints": true + }, + { + "idx": 17, + "version": "7", + "when": 1755637642205, + "tag": "0017_melted_meggan", + "breakpoints": true + }, + { + "idx": 18, + "version": "7", + "when": 1755858317109, + "tag": "0018_puzzling_arachne", + "breakpoints": true + }, + { + "idx": 19, + "version": "7", + "when": 1755906116757, + "tag": "0019_complete_moondragon", + "breakpoints": true + }, + { + "idx": 20, + "version": "7", + "when": 1755907709198, + "tag": "0020_strange_colonel_america", + "breakpoints": true + }, + { + "idx": 21, + "version": "7", + "when": 1756063134903, + "tag": "0021_colossal_madame_web", + "breakpoints": true } ] } \ No newline at end of file diff --git a/backend/src/middlewares/multer.middleware.ts b/backend/src/middlewares/multer.middleware.ts index 7ad120f..184b4d4 100644 --- a/backend/src/middlewares/multer.middleware.ts +++ b/backend/src/middlewares/multer.middleware.ts @@ -1,45 +1,78 @@ import multer from "multer"; import path from "path"; -import fs from "fs"; - -// Dossier de destination -const uploadPath = path.join(__dirname, "../../uploads/imgnews"); - -// Crée le dossier s’il n’existe pas -if (!fs.existsSync(uploadPath)) { - fs.mkdirSync(uploadPath, { recursive: true }); -} - -// Configuration du storage -const storage = multer.diskStorage({ - destination: (req, file, cb) => { - cb(null, uploadPath); - }, - filename: (req, file, cb) => { - const timestamp = Date.now(); - const ext = path.extname(file.originalname); - const baseName = path.basename(file.originalname, ext); - cb(null, `${baseName}-${timestamp}${ext}`); - }, -}); - -// Filtrer les types de fichiers (optionnel) -const fileFilter = (req: any, file: Express.Multer.File, cb: multer.FileFilterCallback) => { - - if (file.mimetype.startsWith("image/")) { - cb(null, true); - } else { - cb(new Error("Seules les images sont autorisées")); - } -}; +import fs from "fs/promises"; +import { Request, Response, NextFunction } from "express"; +import { fileTypeFromBuffer } from "file-type"; +import { Error } from "../utils/responses"; + +export const createUploadMiddleware = ( + relativeUploadDir: string, + modifiedName: boolean = true + ) => { + const uploadPath = path.resolve(process.cwd(), relativeUploadDir); + + // On stocke d'abord en mémoire pour vérifier le type réel + const storage = multer.memoryStorage(); + + const multerUpload = multer({ + storage, + limits: { + fileSize: 5 * 1024 * 1024, // 5 Mo + }, + }); + + // Middleware custom pour vérifier et sauvegarder + const verifyAndSave = async ( + req: Request, + res: Response, + next: NextFunction + ) => { + try { + if (!req.file) return Error(res, {msg: "Aucun fichier reçu"}); + + const user = (req as Request).user?.userId || "anonymous"; + const { originalname, mimetype, buffer } = req.file; + + console.log( + `[UPLOAD] User: ${user}, File: ${originalname}, Mimetype annoncé: ${mimetype}` + ); + + // Vérif du vrai type + const detected = await fileTypeFromBuffer(buffer); + console.log( + `[UPLOAD] Type détecté: ${detected?.mime || "inconnu"}` + ); -// Final middleware -const upload = multer({ - storage, - fileFilter, - limits: { - fileSize: 5 * 1024 * 1024, // 5 Mo - }, -}); + const isImage = detected?.mime?.startsWith("image/"); + const isPDF = detected?.mime === "application/pdf"; -export default upload; + if (!isImage && !isPDF) { + return Error(res,{ msg:"Seules les images et les PDF sont autorisés"}); + } + + // Création dossier si nécessaire + await fs.mkdir(uploadPath, { recursive: true }); + + const ext = path.extname(originalname); + const baseName = path.basename(originalname, ext); + const timestamp = Date.now(); + const finalName = modifiedName + ? `${baseName}-${timestamp}${ext}` + : originalname; + + const finalPath = path.join(uploadPath, finalName); + + // Sauvegarde du fichier sur disque + await fs.writeFile(finalPath, buffer); + + // On rajoute le chemin pour les middlewares suivants + (req as any).savedFilePath = finalPath; + + next(); + } catch (err) { + next(err); + } + }; + + return { multerUpload, verifyAndSave }; +}; diff --git a/backend/src/middlewares/respoperm.middleware.ts b/backend/src/middlewares/respoperm.middleware.ts new file mode 100644 index 0000000..c9b3915 --- /dev/null +++ b/backend/src/middlewares/respoperm.middleware.ts @@ -0,0 +1,29 @@ +import { Request, Response, NextFunction } from "express"; +import { Error } from "../utils/responses"; +import { isUserRespoOfPermanence } from "../services/permanence.service"; + +export const isRespoMiddleware = async ( + req: Request, + res: Response, + next: NextFunction +) => { + const userId = req.user?.userId; + + if (!userId) { + Error(res, { msg: "Utilisateur ou permanence non spécifié" }); + return; + } + + try { + const isRespo = await isUserRespoOfPermanence(userId); + if (!isRespo) { + Error(res, { msg: "Accès refusé : vous n'êtes pas responsable d'une permanence" }); + return; + } + + next(); // ✅ L'utilisateur est bien respo, on continue + } catch (err) { + console.error(err); + Error(res, { msg: "Erreur lors de la vérification du responsable" }); + } +}; \ No newline at end of file diff --git a/backend/src/routes/event.routes.ts b/backend/src/routes/event.routes.ts index d729ee0..62c60d4 100644 --- a/backend/src/routes/event.routes.ts +++ b/backend/src/routes/event.routes.ts @@ -11,6 +11,7 @@ eventRouter.get("/user/preregisterstatus",checkRole("Student",[]), eventControll eventRouter.get("/user/sdistatus", eventController.checkSDIStatus); eventRouter.get("/user/weistatus", eventController.checkWEIStatus); eventRouter.get("/user/foodstatus", eventController.checkFoodStatus); +eventRouter.get("/user/challstatus", eventController.checkChallStatus); eventRouter.post("/user/shotgunattempt",checkRole("Student",[]), eventController.shotgunAttempt); @@ -20,5 +21,6 @@ eventRouter.post("/admin/preregistrationtoggle",checkRole("Admin",[]), eventCont eventRouter.post("/admin/sditoggle",checkRole("Admin",[]),eventController.toggleSDI); eventRouter.post("/admin/weitoggle",checkRole("Admin",[]), eventController.toggleWEI); eventRouter.post("/admin/foodtoggle",checkRole("Admin",[]), eventController.toggleFood); +eventRouter.post("/admin/challtoggle",checkRole("Admin",[]), eventController.toggleChall); export default eventRouter; \ No newline at end of file diff --git a/backend/src/routes/export.routes.ts b/backend/src/routes/export.routes.ts deleted file mode 100644 index 6451ac5..0000000 --- a/backend/src/routes/export.routes.ts +++ /dev/null @@ -1,12 +0,0 @@ -import express from 'express'; -import * as exportController from '../controllers/export.controller'; -import { checkRole } from '../middlewares/user.middleware'; - -const exportRouter = express.Router(); - -// Route d'inscription -exportRouter.post('/admin/export',checkRole("Admin",[]), exportController.exportAllDataToSheets) - - - -export default exportRouter; diff --git a/backend/src/routes/im_export.routes.ts b/backend/src/routes/im_export.routes.ts new file mode 100644 index 0000000..42cec07 --- /dev/null +++ b/backend/src/routes/im_export.routes.ts @@ -0,0 +1,19 @@ +import express from 'express'; +import * as imexportController from '../controllers/im_export.controller'; +import { checkRole } from '../middlewares/user.middleware'; +import {createUploadMiddleware} from "../middlewares/multer.middleware"; + +const uploadFoodMenu = createUploadMiddleware("uploads/foodmenu/", false); +const uploadPlannings = createUploadMiddleware("uploads/plannings/", false); +const imexportRouter = express.Router(); + + +imexportRouter.post('/admin/foodimport',checkRole("Admin",[]),uploadFoodMenu.multerUpload.single("foodFile"), uploadFoodMenu.verifyAndSave, imexportController.updateFoodMenu); +imexportRouter.post('/admin/plannings',checkRole("Admin",[]),uploadPlannings.multerUpload.single("planningFile"), uploadPlannings.verifyAndSave, imexportController.updatePlannings); +imexportRouter.post('/admin/exportgsheet',checkRole("Admin",[]), imexportController.exportAllDataToSheets); +imexportRouter.get('/admin/exportbus',checkRole("Admin",[]), imexportController.exportUsersCSV); + + + + +export default imexportRouter; diff --git a/backend/src/routes/news.routes.ts b/backend/src/routes/news.routes.ts index 35b3db4..a6cb339 100644 --- a/backend/src/routes/news.routes.ts +++ b/backend/src/routes/news.routes.ts @@ -1,16 +1,19 @@ import express from "express"; import * as newsController from "../controllers/news.controller"; import { checkRole } from "../middlewares/user.middleware"; -import upload from "../middlewares/multer.middleware"; +import { createUploadMiddleware } from "../middlewares/multer.middleware"; +const uploadImgNews = createUploadMiddleware("uploads/imgnews/", true); const newsRouter = express.Router(); + //Admin routes -newsRouter.post("/admin/createnews",checkRole("Admin",["Communication"]), upload.single("file"), newsController.createNews); +newsRouter.post("/admin/createnews",checkRole("Admin",["Communication"]), uploadImgNews.multerUpload.single("file"), uploadImgNews.verifyAndSave, newsController.createNews); +newsRouter.post("/admin/updatenews", checkRole("Admin", ["Communication"]), uploadImgNews.multerUpload.single("file"), uploadImgNews.verifyAndSave, newsController.updateNews); newsRouter.get("/admin/all",checkRole("Admin",["Communication"]), newsController.listAllNews); newsRouter.post("/admin/publish",checkRole("Admin",["Communication"]) , newsController.publishNews); newsRouter.delete("/admin/deletenews",checkRole("Admin",["Communication"]) ,newsController.deleteNews); -newsRouter.post("/admin/updatenews", checkRole("Admin", ["Communication"]), upload.single("file"), newsController.updateNews); + //User routes diff --git a/backend/src/routes/permanences.routes.ts b/backend/src/routes/permanences.routes.ts index 6f167b1..a5d2f6d 100644 --- a/backend/src/routes/permanences.routes.ts +++ b/backend/src/routes/permanences.routes.ts @@ -2,6 +2,7 @@ import express from "express"; import multer from "multer"; import * as permanenceController from "../controllers/permanence.controller"; import { checkRole } from "../middlewares/user.middleware"; +import { isRespoMiddleware } from "../middlewares/respoperm.middleware"; const permanenceRouter = express.Router(); const upload = multer({ dest: "uploads/permcsv/" }); @@ -18,11 +19,16 @@ permanenceRouter.post("/admin/add", checkRole("Admin",[]), permanenceController. permanenceRouter.post("/admin/remove", checkRole("Admin",[]), permanenceController.removeUserToPermanence); permanenceRouter.post("/admin/importpermanences",checkRole("Admin",[]), upload.single("file"), permanenceController.uploadPermanencesCSV); +//Respo de perm routes + +permanenceRouter.get("/respo/respodetails",isRespoMiddleware, permanenceController.getRespoPermanencesWithMembers); +permanenceRouter.post("/respo/claimedmember",isRespoMiddleware, permanenceController.claimMember); + // Student routes permanenceRouter.get("/user/permanences", checkRole("Student",[]), permanenceController.getOpenPermanences); permanenceRouter.post("/user/apply", checkRole("Student",[]), permanenceController.applyToPermanence); permanenceRouter.post("/user/leave", checkRole("Student",[]), permanenceController.leavePermanence); permanenceRouter.get("/user/me", checkRole("Student",[]), permanenceController.getMyPermanences ); - +permanenceRouter.get("/user/isrespo", permanenceController.isUserRespo); export default permanenceRouter; diff --git a/backend/src/routes/tent.routes.ts b/backend/src/routes/tent.routes.ts new file mode 100644 index 0000000..de98ac2 --- /dev/null +++ b/backend/src/routes/tent.routes.ts @@ -0,0 +1,21 @@ +import express from 'express'; +import * as tentController from '../controllers/tent.controller'; +import { checkRole } from '../middlewares/user.middleware'; + +const tentRouter = express.Router(); + +// Admin routes +tentRouter.get('/admin/tents', checkRole("Admin",[]), tentController.getAllTentPairs); +tentRouter.post('/admin/toggleconfirmation', checkRole("Admin",[]), tentController.toggleTentConfirmation); + + +// User routes +tentRouter.post("/user/tent",checkRole("Nouveau",[]), tentController.createTent); +tentRouter.delete("/user/tent",checkRole("Nouveau",[]), tentController.cancelTent); +tentRouter.get("/user/tent",checkRole("Nouveau",[]), tentController.getUserTent); + + + + + +export default tentRouter; diff --git a/backend/src/routes/user.routes.ts b/backend/src/routes/user.routes.ts index 3095ab7..e0149c6 100644 --- a/backend/src/routes/user.routes.ts +++ b/backend/src/routes/user.routes.ts @@ -1,6 +1,5 @@ import express from 'express'; import * as userController from '../controllers/user.controller'; -import { authenticateUser } from '../middlewares/auth.middleware'; import { checkRole } from '../middlewares/user.middleware'; const userRouter = express.Router(); @@ -14,9 +13,9 @@ userRouter.post('/admin/syncnewstudent', checkRole("Admin",[]), userController.s // User routes -userRouter.patch('/user/me', authenticateUser, userController.updateProfile); -userRouter.get('/user/me', authenticateUser, userController.getCurrentUser); -userRouter.get('/user/getusers', checkRole("Student",[]), userController.getUsers); +userRouter.patch('/user/me', userController.updateProfile); +userRouter.get('/user/me', userController.getCurrentUser); +userRouter.get('/user/getusers', userController.getUsers); diff --git a/backend/src/schemas/Basic/event.schema.ts b/backend/src/schemas/Basic/event.schema.ts index 759945e..a6b4764 100644 --- a/backend/src/schemas/Basic/event.schema.ts +++ b/backend/src/schemas/Basic/event.schema.ts @@ -6,7 +6,8 @@ export const eventSchema = pgTable("events", { shotgun_open: boolean("shotgun_open").default(false), sdi_open: boolean("sdi_open").default(false), wei_open: boolean("wei_open").default(false), - food_open: boolean("wei_open").default(false), + food_open: boolean("food_open").default(false), + chall_open: boolean("chall_open").default(false), }); export type Event = typeof eventSchema.$inferSelect; \ No newline at end of file diff --git a/backend/src/schemas/Basic/permanence.schema.ts b/backend/src/schemas/Basic/permanence.schema.ts index d720593..25cb42a 100644 --- a/backend/src/schemas/Basic/permanence.schema.ts +++ b/backend/src/schemas/Basic/permanence.schema.ts @@ -15,7 +15,8 @@ export const permanenceSchema = pgTable("permanences", { start_at: timestamp("start_at"), end_at: timestamp("end_at"), capacity: integer("capacity"), - is_open: boolean("is_open").default(false), // Géré par l'admin + is_open: boolean("is_open").default(false), + difficulty: integer("difficulty") }); export type Permanence = typeof permanenceSchema.$inferSelect; diff --git a/backend/src/schemas/Relational/userpermanences.schema.ts b/backend/src/schemas/Relational/userpermanences.schema.ts index 2a94249..2cbfe55 100644 --- a/backend/src/schemas/Relational/userpermanences.schema.ts +++ b/backend/src/schemas/Relational/userpermanences.schema.ts @@ -1,4 +1,4 @@ -import { pgTable, integer, primaryKey, timestamp } from "drizzle-orm/pg-core"; +import { pgTable, integer, primaryKey, timestamp, boolean } from "drizzle-orm/pg-core"; import { userSchema } from "../Basic/user.schema"; import { permanenceSchema } from "../Basic/permanence.schema"; @@ -6,9 +6,20 @@ export const userPermanenceSchema = pgTable("user_permanences", { user_id: integer("user_id").references(() => userSchema.id, { onDelete: "cascade" }), permanence_id: integer("permanence_id").references(() => permanenceSchema.id, { onDelete: "cascade" }), registered_at: timestamp("registered_at").defaultNow(), + claimed: boolean("claimed").default(false), }, (table) => [ primaryKey({ columns: [table.user_id, table.permanence_id] }), ]); export type UserPermanence = typeof userPermanenceSchema.$inferSelect; + +export const respoPermanenceSchema = pgTable("respo_permanences", { + user_id: integer("user_id").references(() => userSchema.id, { onDelete: "cascade" }), + permanence_id: integer("permanence_id").references(() => permanenceSchema.id, { onDelete: "cascade" }), +}, +(table) => [ + primaryKey({ columns: [table.user_id, table.permanence_id] }), +]); + +export type RespoPermanence = typeof userPermanenceSchema.$inferSelect; diff --git a/backend/src/schemas/Relational/usertent.schema.ts b/backend/src/schemas/Relational/usertent.schema.ts new file mode 100644 index 0000000..6991e3e --- /dev/null +++ b/backend/src/schemas/Relational/usertent.schema.ts @@ -0,0 +1,14 @@ +import { pgTable, serial, integer, primaryKey, boolean, timestamp } from "drizzle-orm/pg-core"; +import { userSchema } from "../Basic/user.schema"; + +export const userTentSchema = pgTable("user_tent", { + user_id_1: integer("user_id_1").references(() => userSchema.id, { onDelete: "cascade" }), + user_id_2: integer("user_id_2").references(() => userSchema.id, { onDelete: "cascade" }), + confirmed: boolean("confirmed").default(false), // optionnel : pour savoir si les deux ont validé + created_at: timestamp("created_at").defaultNow(), +}, (table) => [ + primaryKey({ columns: [table.user_id_1, table.user_id_2] }), +]); + + +export type UserTent = typeof userTentSchema.$inferSelect; \ No newline at end of file diff --git a/backend/src/services/event.service.ts b/backend/src/services/event.service.ts index 16e74da..b3003d6 100644 --- a/backend/src/services/event.service.ts +++ b/backend/src/services/event.service.ts @@ -72,4 +72,10 @@ export const updateFoodStatus = async ( foodOpen: boolean) => { return await db.update(eventSchema) .set({ food_open: foodOpen }) .returning(); +}; + +export const updateChallStatus = async (challOpen: boolean) => { + return await db.update(eventSchema) + .set({ chall_open: challOpen }) + .returning(); }; \ No newline at end of file diff --git a/backend/src/services/export.service.ts b/backend/src/services/export.service.ts deleted file mode 100644 index 1feacd1..0000000 --- a/backend/src/services/export.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -// src/services/googleSheets.service.ts -import { google } from 'googleapis'; -import { JWT } from 'google-auth-library'; - -const path = require('path'); -const keyFilePath = path.resolve(__dirname, '../utils/google_credentials.json'); - -// Crée une instance JWT en utilisant la clé du service account -const jwtClient = new JWT({ - keyFile: keyFilePath, - scopes: ['https://www.googleapis.com/auth/spreadsheets'], -}); - -// Fonction pour écrire dans Google Sheets -export const writeToGoogleSheet = async ( - spreadsheetId: string, - range: string, - values: any[][] -) => { - try { - // Crée un client Sheets en utilisant JWT pour l'authentification - const sheets = google.sheets({ version: 'v4', auth: jwtClient }); - - // Appel pour écrire les données dans la feuille - await sheets.spreadsheets.values.update({ - spreadsheetId, - range, - valueInputOption: 'RAW', - requestBody: { - values, - }, - }); - - console.log(`Données envoyées à Google Sheets dans la plage ${range}`); - } catch (error) { - console.error('Erreur lors de l\'écriture dans Google Sheets:', error); - throw error; - } -}; diff --git a/backend/src/services/im_export.service.ts b/backend/src/services/im_export.service.ts new file mode 100644 index 0000000..44c9a62 --- /dev/null +++ b/backend/src/services/im_export.service.ts @@ -0,0 +1,87 @@ +// src/services/googleSheets.service.ts +import { google } from 'googleapis'; +import { JWT } from 'google-auth-library'; +import { existsSync, mkdirSync, writeFileSync } from "fs"; +import { parse } from "json2csv"; +import * as user_service from './user.service'; + + +const path = require('path'); +const keyFilePath = path.resolve(__dirname, '../utils/google_credentials.json'); + +// Crée une instance JWT en utilisant la clé du service account +const jwtClient = new JWT({ + keyFile: keyFilePath, + scopes: ['https://www.googleapis.com/auth/spreadsheets'], +}); + +// Fonction pour écrire dans Google Sheets +export const writeToGoogleSheet = async ( + spreadsheetId: string, + range: string, + values: any[][] +) => { + try { + // Crée un client Sheets en utilisant JWT pour l'authentification + const sheets = google.sheets({ version: 'v4', auth: jwtClient }); + + // Appel pour écrire les données dans la feuille + await sheets.spreadsheets.values.update({ + spreadsheetId, + range, + valueInputOption: 'RAW', + requestBody: { + values, + }, + }); + + console.log(`Données envoyées à Google Sheets dans la plage ${range}`); + } catch (error) { + console.error('Erreur lors de l\'écriture dans Google Sheets:', error); + throw error; + } +}; + + +export const exportUsersToCSV = async (): Promise => { + const users = await user_service.getUsersAll(); + + const formattedUsers = users.map(u => { + const isOrga = u.roles && u.roles.length > 0; + const isCE = u.permission === "Student" && u.teamId !== null; + const isBenevole = u.roles.some(role => role.roleName === "Bénévole"); + + return { + userId: u.id, + prenom: u.first_name ?? "", + nom: u.last_name ?? "", + mail: u.email ?? "", + telephone: u.contact ?? "", + nouveau: u.permission === "Nouveau", + ce: isCE, + num_equipe: u.teamId ?? null, + benevole: isBenevole, + orga: isOrga, + majeur: u.majeur ?? false, + }; + }); + + const csv = parse(formattedUsers, { + fields: [ + "id", "prenom", "nom", "mail", "telephone", + "nouveau", "ce", "num_equipe", "benevole", "orga", "majeur", "bus_manual" + ] + }); + + const exportDir = path.join(__dirname, "../../exports/bus"); + const filePath = path.join(exportDir, "bus.csv"); + + if (!existsSync(exportDir)) { + mkdirSync(exportDir, { recursive: true }); + } + + writeFileSync(filePath, csv); + + return filePath; + +}; diff --git a/backend/src/services/permanence.service.ts b/backend/src/services/permanence.service.ts index ccde2b1..f98d1a1 100644 --- a/backend/src/services/permanence.service.ts +++ b/backend/src/services/permanence.service.ts @@ -1,19 +1,20 @@ import fs from "fs"; import Papa from "papaparse"; -import { and, count, eq, sql } from "drizzle-orm"; +import { and, count, eq, inArray, sql } from "drizzle-orm"; import { userSchema } from "../schemas/Basic/user.schema"; import { permanenceSchema } from "../schemas/Basic/permanence.schema"; import { db } from "../database/db"; -import { userPermanenceSchema } from "../schemas/Relational/userpermanences.schema"; +import { respoPermanenceSchema, userPermanenceSchema } from "../schemas/Relational/userpermanences.schema"; type CsvPermanence = { name: string; description: string; location: string; - start_at: string; // ISO string + start_at: string; end_at: string; capacity: string; - is_open: string; // 'true' or 'false' + is_open: string; + difficulty: string; }; // Classes d'erreurs personnalisées @@ -146,26 +147,53 @@ export const createPermanence = async ( location: string, start_at: Date, end_at: Date, - capacity: number + capacity: number, + difficulty: number, + respoId: number ) => { - await db.insert(permanenceSchema).values({ - name, - description, - location, - start_at, - end_at, - capacity, - is_open: false, // pas ouverte à la création - }); + // Étape 1 : Création de la permanence + const [newPermanence] = await db + .insert(permanenceSchema) + .values({ + name, + description, + location, + start_at, + end_at, + capacity, + is_open: false, + difficulty, + }) + .returning({ id: permanenceSchema.id }); + + // Étape 2 : Ajout du responsable + if (newPermanence?.id && respoId) { + await db.insert(respoPermanenceSchema).values({ + user_id: respoId, + permanence_id: newPermanence.id, + }); + } }; + export const deletePermanence = async (permId: number) => { + // Étape 1 : Supprimer les inscriptions des utilisateurs await db .delete(userPermanenceSchema) .where(eq(userPermanenceSchema.permanence_id, permId)); - await db.delete(permanenceSchema).where(eq(permanenceSchema.id, permId)); + + // Étape 2 : Supprimer les responsables associés + await db + .delete(respoPermanenceSchema) + .where(eq(respoPermanenceSchema.permanence_id, permId)); + + // Étape 3 : Supprimer la permanence + await db + .delete(permanenceSchema) + .where(eq(permanenceSchema.id, permId)); }; + export const updatePermanence = async ( permId: number, name: string, @@ -173,8 +201,11 @@ export const updatePermanence = async ( location: string, start_at: Date, end_at: Date, - capacity: number + capacity: number, + difficulty: number, + respoId: number ) => { + // Étape 1 : Mise à jour de la permanence await db .update(permanenceSchema) .set({ @@ -184,11 +215,26 @@ export const updatePermanence = async ( start_at, end_at, capacity, - is_open: false, // pas ouverte à la création + is_open: false, + difficulty, }) .where(eq(permanenceSchema.id, permId)); + + // Étape 2 : Suppression des anciens responsables (si nécessaire) + await db + .delete(respoPermanenceSchema) + .where(eq(respoPermanenceSchema.permanence_id, permId)); + + // Étape 3 : Ajout du nouveau responsable + if(respoId){ + await db.insert(respoPermanenceSchema).values({ + user_id: respoId, + permanence_id: permId, + }); + } }; + // Ouvrir une permanence (Admin action) export const openPermanence = async (permId: number) => { await db @@ -197,7 +243,7 @@ export const openPermanence = async (permId: number) => { .where(eq(permanenceSchema.id, permId)); }; -// Fermer une permanence +// Fermer une permanence (Admin action) export const closePermanence = async (permId: number) => { await db .update(permanenceSchema) @@ -220,7 +266,7 @@ export const modifyPermCap = async (permId: number, factor: number) => { // Voir ses permanences export const getMyPermanences = async (userId: number) => { - return await db + const userPerms = await db .select({ id: permanenceSchema.id, name: permanenceSchema.name, @@ -234,24 +280,75 @@ export const getMyPermanences = async (userId: number) => { eq(permanenceSchema.id, userPermanenceSchema.permanence_id) ) .where(eq(userPermanenceSchema.user_id, userId)); + + // Ajout du responsables + const results = await Promise.all( + userPerms.map(async (perm) => { + const [respo] = await db + .select({ + id: userSchema.id, + firstName: userSchema.first_name, + lastName: userSchema.last_name, + email: userSchema.email, + }) + .from(respoPermanenceSchema) + .innerJoin(userSchema, eq(userSchema.id, respoPermanenceSchema.user_id)) + .where(eq(respoPermanenceSchema.permanence_id, perm.id)); + + return { + ...perm, + respo: respo ?? null, + }; + }) + ); + + + return results; }; + export const getAllPermanences = async () => { - return await db.select().from(permanenceSchema); + const perms = await db.select().from(permanenceSchema); + + const results = await Promise.all( + perms.map(async (perm) => { + const [respo] = await db + .select({ + userId: userSchema.id, + firstName: userSchema.first_name, + lastName: userSchema.last_name, + email: userSchema.email, + }) + .from(respoPermanenceSchema) + .innerJoin(userSchema, eq(userSchema.id, respoPermanenceSchema.user_id)) + .where(eq(respoPermanenceSchema.permanence_id, perm.id)); + + return { + ...perm, + respo: respo ?? null, + }; + }) + ); + + + return results; }; + export const getUsersInPermanence = async (permId: number) => { return await db .select({ userId: userSchema.id, firstName: userSchema.first_name, lastName: userSchema.last_name, + claimed: userPermanenceSchema.claimed, }) .from(userPermanenceSchema) .innerJoin(userSchema, eq(userSchema.id, userPermanenceSchema.user_id)) .where(eq(userPermanenceSchema.permanence_id, permId)); }; + export const addUserToPermanence = async (userId: number, permId: number) => { // Désinscrire l'utilisateur await db.insert(userPermanenceSchema).values({ @@ -280,14 +377,18 @@ export const removeUserToPermanence = async ( export const getAllPermanencesWithUsers = async () => { // Récupère toutes les permanences - const permanences = await db.select().from(permanenceSchema); + const permanences = await getAllPermanences(); - // Pour chaque permanence, on récupère les users associés + // Pour chaque permanence, on récupère les users associés avec leur statut claimed const results = await Promise.all( permanences.map(async (permanence) => { const userRelations = await db .select({ - user: userSchema, + id: userSchema.id, + first_name: userSchema.first_name, + last_name: userSchema.last_name, + email: userSchema.email, + claimed: userPermanenceSchema.claimed, }) .from(userPermanenceSchema) .innerJoin(userSchema, eq(userSchema.id, userPermanenceSchema.user_id)) @@ -295,7 +396,7 @@ export const getAllPermanencesWithUsers = async () => { return { ...permanence, - users: userRelations.map((entry) => entry.user), + users: userRelations, }; }) ); @@ -325,8 +426,78 @@ export const importPermanencesFromCSV = async ( start_at: new Date(r.start_at), end_at: new Date(r.end_at), capacity: parseInt(r.capacity, 10), - is_open: r.is_open?.toLowerCase() === "true", + difficulty: r.difficulty, + is_open: false, + })); await db.insert(permanenceSchema).values(parsedData); }; + +export const isUserRespoOfPermanence = async ( + userId: number, +): Promise => { + const respo = await db + .select() + .from(respoPermanenceSchema) + .where( + eq(respoPermanenceSchema.user_id, userId) + ); + + return respo.length > 0; +}; + +export const getPermanenceDetailsForRespo = async (respoId: number) => { + // Étape 1 : Trouver les permanences dont il est respo + const respos = await db + .select() + .from(respoPermanenceSchema) + .where(eq(respoPermanenceSchema.user_id, respoId)); + + const permanenceIds = respos.map((r) => r.permanence_id); + if (permanenceIds.length === 0) throw new Error("Pas de permanences");; + + // Étape 2 : Récupérer les permanences + const permanences = await db + .select() + .from(permanenceSchema) + .where(inArray(permanenceSchema.id, permanenceIds)); + + // Étape 3 : Récupérer les membres avec infos utiles + const results = await Promise.all( + permanences.map(async (perm) => { + const members = await db + .select({ + id: userSchema.id, + first_name: userSchema.first_name, + last_name: userSchema.last_name, + email: userSchema.email, + claimed: userPermanenceSchema.claimed, + }) + .from(userPermanenceSchema) + .innerJoin(userSchema, eq(userSchema.id, userPermanenceSchema.user_id)) + .where(eq(userPermanenceSchema.permanence_id, perm.id)); + + return { + permanence: perm, + members, + }; + }) + ); + + return results; +}; + +export const claimMember = async ( userId: number, permId: number, claimed: boolean ) => { + await db + .update(userPermanenceSchema) + .set({ claimed }) + .where( + and( + eq(userPermanenceSchema.user_id, userId), + eq(userPermanenceSchema.permanence_id, permId) + ) + ); +}; + + diff --git a/backend/src/services/tent.service.ts b/backend/src/services/tent.service.ts new file mode 100644 index 0000000..bab65c0 --- /dev/null +++ b/backend/src/services/tent.service.ts @@ -0,0 +1,136 @@ +import { db } from "../database/db"; +import { and, eq, or } from "drizzle-orm"; +import { userTentSchema } from "../schemas/Relational/usertent.schema"; +import { userSchema } from "../schemas/Basic/user.schema"; +import { alias } from "drizzle-orm/pg-core"; + +/** + * Créer une réservation de tente entre 2 utilisateurs. + */ +export const createTent = async (userId1: number, userId2: number) => { + if (userId1 === userId2) { + throw new Error("Impossible de réserver une tente avec soi-même."); + } + + // Vérifier si l'un des deux a déjà une tente + const existing = await db + .select() + .from(userTentSchema) + .where( + or( + eq(userTentSchema.user_id_1, userId1), + eq(userTentSchema.user_id_2, userId1), + eq(userTentSchema.user_id_1, userId2), + eq(userTentSchema.user_id_2, userId2) + ) + ); + + if (existing.length > 0) { + throw new Error("Un des utilisateurs a déjà une tente."); + } + + return await db.insert(userTentSchema).values({ + user_id_1: userId1, + user_id_2: userId2, + }); +}; + +/** + * Annuler une tente (par l'un ou l'autre des utilisateurs). + */ +export const cancelTent = async (userId1: number) => { + + return await db + .delete(userTentSchema) + .where( + or(eq(userTentSchema.user_id_1, userId1), eq(userTentSchema.user_id_2, userId1)), + ); +}; + +/** + * Récupérer la tente d’un utilisateur. + */ +export const getTentByUser = async (userId: number) => { + return await db + .select() + .from(userTentSchema) + .where(or(eq(userTentSchema.user_id_1, userId), eq(userTentSchema.user_id_2, userId))); +}; + +/** + * Récupérer toutes les tentes (avec infos des 2 utilisateurs). + */ +export const getAllTents = async () => { + + const user2 = alias(userSchema, "user2"); + + return await db + .select({ + user1_id: userTentSchema.user_id_1, + user2_id: userTentSchema.user_id_2, + user1_first_name: userSchema.first_name, + user1_last_name: userSchema.last_name, + user1_email: userSchema.email, + user2_first_name: user2.first_name, + user2_last_name: user2.last_name, + user2_email: user2.email, + confirmed: userTentSchema.confirmed + }) + .from(userTentSchema) + .innerJoin(userSchema, eq(userTentSchema.user_id_1, userSchema.id)) + .innerJoin(user2, eq(userTentSchema.user_id_2, user2.id)); +}; + +/** + * Met à jour la confirmation(avec infos des 2 utilisateurs). + */ +export const toggleTentConfirmation = async ( + userId1: number, + userId2: number, + confirmed: boolean +) => { + if (userId1 === userId2) { + throw new Error("Les deux utilisateurs doivent être différents."); + } + + // Vérifier si la tente existe + const existingTent = await db + .select() + .from(userTentSchema) + .where( + or( + and( + eq(userTentSchema.user_id_1, userId1), + eq(userTentSchema.user_id_2, userId2) + ), + and( + eq(userTentSchema.user_id_1, userId2), + eq(userTentSchema.user_id_2, userId1) + ) + ) + ); + + if (existingTent.length === 0) { + throw new Error("La tente entre ces deux utilisateurs n'existe pas."); + } + + // Mettre à jour la confirmation + await db + .update(userTentSchema) + .set({ confirmed }) + .where( + or( + and( + eq(userTentSchema.user_id_1, userId1), + eq(userTentSchema.user_id_2, userId2) + ), + and( + eq(userTentSchema.user_id_1, userId2), + eq(userTentSchema.user_id_2, userId1) + ) + ) + ); + + return { success: true, message: confirmed ? "Tente validée." : "Tente dévalidée." }; +}; + diff --git a/backend/src/services/user.service.ts b/backend/src/services/user.service.ts index 92b0b23..741783f 100644 --- a/backend/src/services/user.service.ts +++ b/backend/src/services/user.service.ts @@ -5,6 +5,9 @@ import { eq } from 'drizzle-orm'; import { userTeamsSchema } from '../schemas/Relational/userteams.schema'; import { getTeam, getTeamFaction, getUserTeam } from './team.service'; import { getFaction } from './faction.service'; +import { registrationSchema } from '../schemas/Relational/registration.schema'; +import { getUserRoles } from './role.service'; +import { permission } from 'process'; // Fonction pour récupérer un utilisateur par email export const getUserByEmail = async (email: string) => { @@ -121,6 +124,7 @@ export const getUsers = async () => { userId: userSchema.id, firstName: userSchema.first_name, lastName: userSchema.last_name, + permission : userSchema.permission } ).from(userSchema); return users; @@ -134,19 +138,36 @@ export const getUsersAll = async () => { try { const users = await db.select().from(userSchema); - const userWithTeam = await Promise.all( - users.map(async (user) => { - const teamId = await getUserTeam(user.id); - const teamName = (await getTeam(teamId))?.teamName; - const factionId = await getTeamFaction(teamId); - const factionName = (await getFaction(factionId))?.name; - return { - ...user, - teamName, - factionName - }; - }) - ); + const userWithTeam = await Promise.all( + users.map(async (user) => { + const roles = await getUserRoles(user.id); + let teamId = await getUserTeam(user.id); + teamId= teamId ?? null; + + let teamName: string | null = null; + let factionId: number | null = null; + let factionName: string | null = null; + + if (teamId) { + const team = await getTeam(teamId); + teamName = team?.teamName ?? null; + + factionId = await getTeamFaction(teamId); + const faction = await getFaction(factionId); + factionName = faction?.name ?? null; + } + + return { + ...user, + teamId, + teamName, + factionId, + factionName, + roles, + }; + }) + ); + return userWithTeam; } catch (err) { @@ -232,6 +253,13 @@ export const updateUserByAdmin = async ( export const deleteUserById = async (userId: number) => { try { + + const user_registration_token = await db.select({user_id : registrationSchema.user_id}).from(registrationSchema).where(eq(registrationSchema.user_id, userId)); + + if(user_registration_token.length > 0){ + await db.delete(registrationSchema).where(eq(registrationSchema.user_id, userId)); + } + const result = await db.delete(userSchema).where(eq(userSchema.id, userId)); return result; } catch (err) { diff --git a/backend/src/utils/emailtemplates.ts b/backend/src/utils/emailtemplates.ts index fc756ee..63eecef 100644 --- a/backend/src/utils/emailtemplates.ts +++ b/backend/src/utils/emailtemplates.ts @@ -345,6 +345,37 @@ export const templateNotifyNews = ` `; +export const templateNotifyTentConfirmation = ` +
+
+ + +
+ Logo Intégration UTT +

Intégration UTT

+
+ + +

⛺ Mise à jour de ta tente

+

+ La tente entre {{user1}} et {{user2}} a été + + {{#if confirmed}}validée{{else}}dévalidée{{/if}} + . +

+ +

+ 👉 Tu peux consulter l’état de ta tente sur le site de l'inté dans l’onglet Tentes. +

+ + +

+ Accéder au site +

+
+
+`; + // Fonction pour compiler le template diff --git a/backend/src/utils/no_sync_list.ts b/backend/src/utils/no_sync_list.ts new file mode 100644 index 0000000..46cd864 --- /dev/null +++ b/backend/src/utils/no_sync_list.ts @@ -0,0 +1,4 @@ +//This list is to ignore user from UTT API who already have an account on the website but not with the same email address +// OR People we don't want to sync like "BIO REF" or demissionary +export const noSyncEmails = [ +]; \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 87aa4ca..9c29e08 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -14,7 +14,7 @@ ENV VITE_ANALYTICS_WEBSITE_ID=${VITE_ANALYTICS_WEBSITE_ID} COPY package.json package-lock.json ./ RUN npm install -g npm@latest -RUN npm install --force +RUN npm install COPY . . RUN npm run build diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ad9faed..b7c3d0a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,26 +9,29 @@ "version": "1.0.0", "dependencies": { "@headlessui/react": "^2.2.7", + "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-checkbox": "^1.1.5", "@radix-ui/react-label": "^2.1.3", "@radix-ui/react-popover": "^1.1.7", "@radix-ui/react-select": "^2.1.7", "@radix-ui/react-slot": "^1.2.0", "@tailwindcss/vite": "^4.1.3", + "@tanstack/react-query": "^5.85.5", "axios": "^1.8.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^3.6.0", - "framer-motion": "^12.7.4", + "framer-motion": "^12.23.12", "jwt-decode": "^4.0.0", "lucide-react": "^0.488.0", - "react": "^19.1.1", + "react": "^19.1.0", "react-day-picker": "^8.10.1", - "react-dom": "^19.1.1", + "react-dom": "^19.0.0", "react-hook-form": "^7.55.0", "react-icons": "^5.5.0", "react-router-dom": "^7.5.0", "react-select": "^5.10.1", + "shadcn": "^2.10.0", "sweetalert2": "^11.6.13", "swiper": "^11.2.6", "tailwind-merge": "^3.2.0", @@ -37,6 +40,7 @@ }, "devDependencies": { "@eslint/js": "^9.21.0", + "@heroicons/react": "^2.2.0", "@types/node": "^22.14.1", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", @@ -63,6 +67,21 @@ "node": ">=6.0.0" } }, + "node_modules/@antfu/ni": { + "version": "23.3.1", + "resolved": "https://registry.npmjs.org/@antfu/ni/-/ni-23.3.1.tgz", + "integrity": "sha512-C90iyzm/jLV7Lomv2UzwWUzRv9WZr1oRsFRKsX5HjQL4EXrbi9H/RtBkjCP+NF+ABZXUKpAa4F1dkoTaea4zHg==", + "license": "MIT", + "bin": { + "na": "bin/na.mjs", + "nci": "bin/nci.mjs", + "ni": "bin/ni.mjs", + "nlx": "bin/nlx.mjs", + "nr": "bin/nr.mjs", + "nu": "bin/nu.mjs", + "nun": "bin/nun.mjs" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -81,7 +100,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -91,7 +109,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -119,13 +136,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -134,11 +151,22 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.27.2", @@ -151,6 +179,27 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", + "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", @@ -160,6 +209,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", @@ -177,7 +239,6 @@ "version": "7.27.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -191,16 +252,57 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-plugin-utils": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -223,7 +325,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -233,7 +334,6 @@ "version": "7.27.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", - "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", @@ -244,12 +344,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.0" + "@babel/types": "^7.28.2" }, "bin": { "parser": "bin/babel-parser.js" @@ -258,6 +358,21 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", @@ -290,6 +405,25 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", + "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.27.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", @@ -314,17 +448,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", + "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", + "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", + "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", + "@babel/types": "^7.28.2", "debug": "^4.3.1" }, "engines": { @@ -332,9 +466,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz", - "integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -344,6 +478,43 @@ "node": ">=6.9.0" } }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", + "license": "ISC", + "dependencies": { + "cookie": "^0.7.2" + } + }, + "node_modules/@bundled-es-modules/cookie/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "license": "ISC", + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "license": "ISC", + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", @@ -1107,6 +1278,16 @@ "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, + "node_modules/@heroicons/react": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", + "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": ">= 16 || ^19.0.0-rc" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1173,6 +1354,92 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@inquirer/confirm": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.15.tgz", + "integrity": "sha512-SwHMGa8Z47LawQN0rog0sT+6JpiL0B7eW9p1Bb7iCeKDGTI5Ez25TSc2l8kw52VV7hA4sX/C78CGkMrKXfuspA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.15", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.15.tgz", + "integrity": "sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==", + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", + "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", + "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -1220,11 +1487,50 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.17.3.tgz", + "integrity": "sha512-JPwUKWSsbzx+DLFznf/QZ32Qa+ptfbUlHhRLrBQBAFu9iI1iYvizM4p+zhhRDceSsPutXp4z+R/HPVphlIiclg==", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.6", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.24.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.39.6.tgz", + "integrity": "sha512-bndDP83naYYkfayr/qhBHMhk0YGwS1iv6vaEGcr0SQbO0IZtbOPqjKjds/WcG+bJA+1T5vCx6kprKOzn5Bg+Vw==", + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -1238,7 +1544,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -1248,7 +1553,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -1258,6 +1562,28 @@ "node": ">= 8" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "license": "MIT" + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "license": "MIT" + }, "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", @@ -1270,6 +1596,43 @@ "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", "license": "MIT" }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", @@ -1323,16 +1686,20 @@ } } }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1349,14 +1716,70 @@ } } }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -2503,6 +2926,32 @@ "vite": "^5.2.0 || ^6 || ^7" } }, + "node_modules/@tanstack/query-core": { + "version": "5.85.5", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.5.tgz", + "integrity": "sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.85.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.5.tgz", + "integrity": "sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.85.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@tanstack/react-virtual": { "version": "3.13.12", "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz", @@ -2530,6 +2979,57 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@ts-morph/common": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.19.0.tgz", + "integrity": "sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.12", + "minimatch": "^7.4.3", + "mkdirp": "^2.1.6", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -2575,6 +3075,12 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -2632,6 +3138,18 @@ "@types/react": "*" } }, + "node_modules/@types/statuses": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.6.tgz", + "integrity": "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==", + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.38.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", @@ -2924,6 +3442,40 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -2947,11 +3499,19 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -2964,11 +3524,49 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2984,7 +3582,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, "node_modules/aria-hidden": { @@ -2999,6 +3596,18 @@ "node": ">=10" } }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3035,9 +3644,59 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -3053,7 +3712,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -3066,7 +3724,6 @@ "version": "4.25.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3095,6 +3752,39 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -3108,6 +3798,22 @@ "node": ">= 0.4" } }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3121,7 +3827,6 @@ "version": "1.0.30001727", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3176,33 +3881,134 @@ "url": "https://polar.sh/cva" } }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, "engines": { - "node": ">=6" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" + "engines": { + "node": ">=6" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", "engines": { - "node": ">=7.0.0" + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/code-block-writer": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz", + "integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/combined-stream": { @@ -3217,6 +4023,15 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3224,11 +4039,31 @@ "dev": true, "license": "MIT" }, + "node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, "license": "MIT" }, "node_modules/cookie": { @@ -3240,6 +4075,28 @@ "node": ">=18" } }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -3269,7 +4126,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -3286,6 +4142,15 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/date-fns": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", @@ -3320,6 +4185,27 @@ "dev": true, "license": "MIT" }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3329,6 +4215,15 @@ "node": ">=0.4.0" } }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -3344,6 +4239,15 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -3368,13 +4272,33 @@ "node": ">= 0.4" } }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.189", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.189.tgz", "integrity": "sha512-y9D1ntS1ruO/pZ/V2FtLE+JXLQe28XoRpZ7QCCo0T8LdQladzdcOVQZH/IWLVJvCw12OGMb6hYOeOAjntCmJRQ==", - "dev": true, "license": "ISC" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.2", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", @@ -3487,12 +4411,17 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3637,6 +4566,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -3683,18 +4625,156 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.5.tgz", + "integrity": "sha512-bSRG85ZrMdmWtm7qkF9He9TNRzc/Bm99gEJMaQoHJ9E6Kv9QBbsldh2oMj7iXmYNEAVvNgvv5vPorG6W+XtBhQ==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3711,7 +4791,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -3724,7 +4803,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -3738,12 +4816,34 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -3761,7 +4861,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -3770,6 +4869,23 @@ "node": ">=8" } }, + "node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -3850,13 +4966,34 @@ "node": ">= 6" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/framer-motion": { - "version": "12.23.6", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.6.tgz", - "integrity": "sha512-dsJ389QImVE3lQvM8Mnk99/j8tiZDM/7706PCqvkQ8sSCnpmWxsgX+g0lj7r5OBVL0U36pIecCTBoIWcM2RuKw==", + "version": "12.23.12", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.12.tgz", + "integrity": "sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==", "license": "MIT", "dependencies": { - "motion-dom": "^12.23.6", + "motion-dom": "^12.23.12", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, @@ -3877,6 +5014,29 @@ } } }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-extra": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3904,16 +5064,24 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -3943,6 +5111,18 @@ "node": ">=6" } }, + "node_modules/get-own-enumerable-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-keys/-/get-own-enumerable-keys-1.0.0.tgz", + "integrity": "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -3956,6 +5136,18 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -4007,6 +5199,15 @@ "dev": true, "license": "MIT" }, + "node_modules/graphql": { + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz", + "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4056,6 +5257,12 @@ "node": ">= 0.4" } }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "license": "MIT" + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -4065,6 +5272,85 @@ "react-is": "^16.7.0" } }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-6.2.1.tgz", + "integrity": "sha512-ONsE3+yfZF2caH5+bJlcddtWqNI3Gvs5A38+ngvljxaBiRXRswym2c7yf8UAeFpRFKjFNHIFEHqR/OLAWJzyiA==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4101,6 +5387,21 @@ "node": ">=0.8.19" } }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4126,17 +5427,24 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -4145,21 +5453,91 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "license": "MIT" + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" } }, + "node_modules/is-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz", + "integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-regexp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", + "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/jiti": { @@ -4181,7 +5559,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -4219,7 +5596,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -4233,7 +5609,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -4242,6 +5617,18 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jwt-decode": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", @@ -4261,6 +5648,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4532,6 +5928,34 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", + "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4548,7 +5972,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -4581,17 +6004,43 @@ "node": ">= 0.4" } }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/memoize-one": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", "license": "MIT" }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -4601,7 +6050,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -4632,6 +6080,18 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4645,6 +6105,15 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -4682,9 +6151,9 @@ } }, "node_modules/motion-dom": { - "version": "12.23.6", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.6.tgz", - "integrity": "sha512-G2w6Nw7ZOVSzcQmsdLc0doMe64O/Sbuc2bVAbgMz6oP/6/pRStKRiVRV4bQfHp5AHYAKEGhEdVHTM+R3FDgi5w==", + "version": "12.23.12", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.12.tgz", + "integrity": "sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==", "license": "MIT", "dependencies": { "motion-utils": "^12.23.6" @@ -4702,6 +6171,59 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/msw": { + "version": "2.10.5", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.10.5.tgz", + "integrity": "sha512-0EsQCrCI1HbhpBWd89DvmxY6plmvrM96b0sCIztnvcNHQbXn5vqwm1KlXslo6u4wN9LFGLC1WFjjgljcQhe40A==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.1", + "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", + "@inquirer/confirm": "^5.0.0", + "@mswjs/interceptors": "^0.39.1", + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.26.1", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.8.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -4727,25 +6249,146 @@ "dev": true, "license": "MIT" }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "license": "MIT" + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", @@ -4761,6 +6404,47 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-6.3.1.tgz", + "integrity": "sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.6.1", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.1.0", + "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", + "strip-ansi": "^7.0.1", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", + "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4823,6 +6507,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4837,7 +6536,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4849,6 +6547,12 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -4868,7 +6572,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -4877,6 +6580,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkce-challenge": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", + "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -4915,6 +6627,28 @@ "node": ">= 0.8.0" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -4926,27 +6660,71 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -4963,27 +6741,37 @@ ], "license": "MIT" }, - "node_modules/react": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", - "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/react-day-picker": { - "version": "8.10.1", - "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz", - "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "node_modules/raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", "license": "MIT", - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/gpbl" + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" }, - "peerDependencies": { - "date-fns": "^2.28.0 || ^3.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, "node_modules/react-dom": { @@ -5183,6 +6971,60 @@ "react-dom": ">=16.6.0" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/recast/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -5212,11 +7054,50 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -5262,11 +7143,35 @@ "fsevents": "~2.3.2" } }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/router/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -5283,70 +7188,430 @@ ], "license": "MIT", "dependencies": { - "queue-microtask": "^1.2.2" + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shadcn": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/shadcn/-/shadcn-2.10.0.tgz", + "integrity": "sha512-/zxjmHGbaYVFtI6bUridFVV7VFStIv3vU/w1h7xenhz7KRzc9pqHsyFvcExZprG7dlA5kW9knRgv8+Cl/H7w9w==", + "license": "MIT", + "dependencies": { + "@antfu/ni": "^23.2.0", + "@babel/core": "^7.22.1", + "@babel/parser": "^7.22.6", + "@babel/plugin-transform-typescript": "^7.22.5", + "@modelcontextprotocol/sdk": "^1.10.2", + "commander": "^10.0.0", + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "diff": "^5.1.0", + "execa": "^7.0.0", + "fast-glob": "^3.3.2", + "fs-extra": "^11.1.0", + "https-proxy-agent": "^6.2.0", + "kleur": "^4.1.5", + "msw": "^2.7.1", + "node-fetch": "^3.3.0", + "ora": "^6.1.2", + "postcss": "^8.4.24", + "prompts": "^2.4.2", + "recast": "^0.23.2", + "stringify-object": "^5.0.0", + "ts-morph": "^18.0.0", + "tsconfig-paths": "^4.2.0", + "zod": "^3.20.2", + "zod-to-json-schema": "^3.24.5" + }, + "bin": { + "shadcn": "dist/index.js" + } + }, + "node_modules/shadcn/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", + "license": "MIT", + "dependencies": { + "bl": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", "license": "MIT" }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { - "shebang-regex": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", + "node_modules/stringify-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-5.0.0.tgz", + "integrity": "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-keys": "^1.0.0", + "is-obj": "^3.0.0", + "is-regexp": "^3.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/stringify-object?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-json-comments": { @@ -5479,6 +7744,12 @@ "node": ">=18" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", @@ -5525,7 +7796,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -5534,6 +7804,39 @@ "node": ">=8.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -5547,6 +7850,30 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-morph": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-18.0.0.tgz", + "integrity": "sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.19.0", + "code-block-writer": "^12.0.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -5575,11 +7902,58 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typescript": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -5620,11 +7994,28 @@ "devOptional": true, "license": "MIT" }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -5655,12 +8046,21 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/use-callback-ref": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", @@ -5727,6 +8127,21 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vite": { "version": "6.3.5", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", @@ -5827,11 +8242,28 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -5853,11 +8285,60 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, "license": "ISC" }, "node_modules/yaml": { @@ -5874,6 +8355,33 @@ "node": ">= 14.6" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -5886,6 +8394,36 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.6", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", + "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } } } -} +} \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index f4e63c6..d3e7d57 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,26 +11,29 @@ }, "dependencies": { "@headlessui/react": "^2.2.7", + "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-checkbox": "^1.1.5", "@radix-ui/react-label": "^2.1.3", "@radix-ui/react-popover": "^1.1.7", "@radix-ui/react-select": "^2.1.7", "@radix-ui/react-slot": "^1.2.0", "@tailwindcss/vite": "^4.1.3", + "@tanstack/react-query": "^5.85.5", "axios": "^1.8.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^3.6.0", - "framer-motion": "^12.7.4", + "framer-motion": "^12.23.12", "jwt-decode": "^4.0.0", "lucide-react": "^0.488.0", - "react": "^19.1.1", + "react": "^19.1.0", "react-day-picker": "^8.10.1", - "react-dom": "^19.1.1", + "react-dom": "^19.0.0", "react-hook-form": "^7.55.0", "react-icons": "^5.5.0", "react-router-dom": "^7.5.0", "react-select": "^5.10.1", + "shadcn": "^2.10.0", "sweetalert2": "^11.6.13", "swiper": "^11.2.6", "tailwind-merge": "^3.2.0", @@ -39,6 +42,7 @@ }, "devDependencies": { "@eslint/js": "^9.21.0", + "@heroicons/react": "^2.2.0", "@types/node": "^22.14.1", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", @@ -51,4 +55,4 @@ "typescript-eslint": "^8.24.1", "vite": "^6.2.0" } -} +} \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index db1fe25..095774f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2,10 +2,10 @@ import React from 'react'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; -import LoginPage from './pages/Auth'; -import { HomePage } from './pages/Home'; -import { ProfilPage } from './pages/Profil'; -import { ShotgunPage } from './pages/Shotgun'; +import LoginPage from './pages/auth'; +import { HomePage } from './pages/home'; +import { ProfilPage } from './pages/profil'; +import { ShotgunPage } from './pages/shotgun'; import { AdminPageRole, AdminPageTeam, @@ -17,24 +17,25 @@ import { AdminPageEmail, AdminPageUser, AdminPageNews, - AdminPageGames -} from './pages/Admin'; + AdminPageGames, + AdminPageTent +} from './pages/admin'; import ProtectedRoute from './components/utils/protectedroute'; import AdminRoute from './components/utils/adminroute'; -import { PermPage } from './pages/Perm'; -import { ChallPage } from './pages/Challenge'; -import { ParrainagePage } from './pages/Parrainage'; -import { RegisterPage } from './pages/Register'; -import { ResetPasswordPage } from './pages/ResetPassword' -import { WeiPage } from './pages/Wei'; -import { SdiPage } from './pages/Sdi'; -import { NewsPage } from './pages/News'; -import { DiscordPage } from './pages/Discord'; -import { Roadbook } from './pages/Roadbook'; +import { AvailablePermanencesPage, MyPermanencesPage, RespoCallPage } from './pages/perm'; +import { ChallPage } from './pages/challenge'; +import { ParrainagePage } from './pages/parrainage'; +import { RegisterPage } from './pages/register'; +import { ResetPasswordPage } from './pages/resetPassword' +import { WeiPage } from './pages/wei'; +import { SdiPage } from './pages/sdi'; +import { NewsPage } from './pages/news'; +import { DiscordPage } from './pages/discord'; import PrivateRoute from './components/utils/privateroute'; -import { GamesPage } from './pages/Games'; -import { FoodPage } from './pages/Food'; +import { GamesPage } from './pages/games'; +import { FoodPage } from './pages/food'; +import { PlanningsPage } from './pages/plannings'; const App: React.FC = () => { @@ -64,6 +65,7 @@ const App: React.FC = () => { {/* Utilisateurs connectés */} } /> + } /> } /> } /> } /> @@ -75,7 +77,9 @@ const App: React.FC = () => { {/* Étudiant et Admin */} } /> - } /> + } /> + } /> + } /> } /> {/* ResposCE et Admin */} @@ -95,6 +99,7 @@ const App: React.FC = () => { } /> } /> } /> + } /> diff --git a/frontend/src/components/Admin/AdminChallenge/adminChalengeList.tsx b/frontend/src/components/Admin/AdminChallenge/adminChalengeList.tsx new file mode 100644 index 0000000..bf2fa71 --- /dev/null +++ b/frontend/src/components/Admin/AdminChallenge/adminChalengeList.tsx @@ -0,0 +1,69 @@ +import { Card } from "../../ui/card"; +import { Button } from "../../ui/button"; +import { Challenge } from "../../../interfaces/challenge.interface"; +import { deleteChallenge } from "../../../services/requests/challenge.service"; +import Swal from "sweetalert2"; +import { Trash2, Edit } from "lucide-react"; + +interface Props { + challenges: Challenge[]; + refreshChallenges: () => void; + onEdit: (c: Challenge) => void; +} + +const AdminChallengeList = ({ challenges, refreshChallenges, onEdit }: Props) => { + const handleDelete = async (id: number) => { + const confirm = await Swal.fire({ + icon: "warning", + title: "Supprimer ?", + text: "Cette action est irréversible", + showCancelButton: true, + confirmButtonText: "Oui, supprimer", + cancelButtonText: "Annuler", + }); + + if (!confirm.isConfirmed) return; + + await deleteChallenge(id); + Swal.fire({ icon: "success", title: "Challenge supprimé !" }); + refreshChallenges(); + }; + + return ( + +

📜 Challenges

+
+ {challenges.map((c) => ( +
+
+

{c.title}

+

{c.description}

+

Catégorie : {c.category}

+

Points : {c.points}

+
+ +
+ + +
+
+ ))} +
+
+ ); +}; + +export default AdminChallengeList; diff --git a/frontend/src/components/Admin/AdminChallenge/adminChallengeAddPointsForm.tsx b/frontend/src/components/Admin/AdminChallenge/adminChallengeAddPointsForm.tsx new file mode 100644 index 0000000..5903831 --- /dev/null +++ b/frontend/src/components/Admin/AdminChallenge/adminChallengeAddPointsForm.tsx @@ -0,0 +1,102 @@ +import { useState, useEffect } from "react"; +import { Input } from "../../ui/input"; +import { Button } from "../../ui/button"; +import Select from "react-select"; +import { getAllFactionsAdmin } from "../../../services/requests/faction.service"; +import { Faction } from "../../../interfaces/faction.interface"; +import Swal from "sweetalert2"; +import { addPointsToFaction } from "../../../services/requests/challenge.service"; + + +export const AdminChallengeAddPointsForm = () => { + const [factions, setFactions] = useState([]); + const [title, setTitle] = useState(""); + const [factionId, setFactionId] = useState(null); + const [points, setPoints] = useState(""); + const [reason, setReason] = useState(""); + + useEffect(() => { + const fetchFactions = async () => { + try { + const response = await getAllFactionsAdmin(); + setFactions(response); + } catch (error) { + Swal.fire("Erreur", "Impossible de récupérer les factions", "error"); + } + }; + fetchFactions(); + }, []); + + const handleSubmit = async () => { + if (!title || !factionId || !points || !reason) { + Swal.fire("Champs manquants", "Tous les champs doivent être remplis", "warning"); + return; + } + + const pointsNumber = Number(points); + if (isNaN(pointsNumber)) { + Swal.fire("Erreur", "Veuillez entrer un nombre valide pour les points", "error"); + return; + } + + try { + const result = await addPointsToFaction({ + title, + factionId, + points: pointsNumber, + reason, + }); + + Swal.fire({ + icon: "success", + title: "Succès", + text: result.message, + timer: 1500, + showConfirmButton: false, + }); + + setTitle(""); + setFactionId(null); + setPoints(""); + setReason(""); + } catch (error) { + Swal.fire("Erreur", "❌ Une erreur est survenue lors de l'ajout des points", "error"); + } + }; + + return ( +
+
+

+ 🎯 Ajouter des points à une faction +

+ + setTitle(e.target.value)} placeholder="Titre du challenge" /> + + setPoints(e.target.value)} placeholder="Nombre de points" /> + + setReason(e.target.value)} placeholder="Raison" /> + +
+ +
+
+
+ ); +}; diff --git a/frontend/src/components/Admin/AdminChallenge/adminChallengeEditor.tsx b/frontend/src/components/Admin/AdminChallenge/adminChallengeEditor.tsx new file mode 100644 index 0000000..3d8a3a8 --- /dev/null +++ b/frontend/src/components/Admin/AdminChallenge/adminChallengeEditor.tsx @@ -0,0 +1,110 @@ +import { useState, useEffect } from "react"; +import { Button } from "../../ui/button"; +import { Input } from "../../ui/input"; +import { Card } from "../../ui/card"; +import Select from "react-select"; +import { createChallenge, updateChallenge } from "../../../services/requests/challenge.service"; +import { Challenge } from "../../../interfaces/challenge.interface"; +import Swal from "sweetalert2"; +import { Loader2 } from "lucide-react"; + +interface Props { + editingChallenge: Challenge | null; + setEditingChallenge: (c: Challenge | null) => void; + refreshChallenges: () => void; +} + +const categoryOptions = [ + { value: "Team", label: "Team" }, + { value: "Faction", label: "Faction" }, + { value: "User", label: "User" }, + { value: "Autre", label: "Autre" }, +]; + +const ChallengeEditor = ({ editingChallenge, setEditingChallenge, refreshChallenges }: Props) => { + const [form, setForm] = useState({ title: "", description: "", category: "", points: 0 }); + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (editingChallenge) { + setForm({ + title: editingChallenge.title, + description: editingChallenge.description, + category: editingChallenge.category, + points: editingChallenge.points, + }); + } + }, [editingChallenge]); + + const resetForm = () => { + setForm({ title: "", description: "", category: "", points: 0 }); + setEditingChallenge(null); + }; + + const handleSubmit = async () => { + setLoading(true); + try { + if (editingChallenge) { + await updateChallenge({ id: editingChallenge.id, ...form }); + Swal.fire({ icon: "success", title: "Challenge mis à jour !" }); + } else { + await createChallenge(form); + Swal.fire({ icon: "success", title: "Challenge créé !" }); + } + refreshChallenges(); + resetForm(); + } catch { + Swal.fire({ icon: "error", title: "Erreur lors de l'enregistrement" }); + } finally { + setLoading(false); + } + }; + + return ( + +

+ {editingChallenge ? "✏️ Modifier Challenge" : "🛠️ Créer Challenge"} +

+ + setForm({ ...form, title: e.target.value })} + /> + setForm({ ...form, description: e.target.value })} + /> + setForm({ ...form, points: Number(e.target.value) })} + /> + +
+ + {editingChallenge && ( + + )} +
+
+ ); +}; + +export default ChallengeEditor; diff --git a/frontend/src/components/Admin/AdminChallenge/adminChallengeValidatedList.tsx b/frontend/src/components/Admin/AdminChallenge/adminChallengeValidatedList.tsx new file mode 100644 index 0000000..8facf02 --- /dev/null +++ b/frontend/src/components/Admin/AdminChallenge/adminChallengeValidatedList.tsx @@ -0,0 +1,106 @@ +import { useState, useEffect } from "react"; +import { Button } from "../../ui/button"; +import { getAllChallengesValidates, unvalidateChallenge } from "../../../services/requests/challenge.service"; +import Swal from "sweetalert2"; + + +export const AdminValidatedChallengesList = () => { + const [validatedChallenges, setValidatedChallenges] = useState([]); + + const fetchValidatedChallenges = async () => { + try { + const challenges = await getAllChallengesValidates(); + setValidatedChallenges(challenges); + } catch { + Swal.fire("Erreur", "Impossible de récupérer les challenges validés", "error"); + } + }; + + useEffect(() => { + fetchValidatedChallenges(); + }, []); + + const handleUnvalidate = async (challengeId: number, factionId: number, teamId: number, userId: number) => { + const confirm = await Swal.fire({ + title: "Confirmer la dévalidation ?", + text: "Cette action retirera la validation du challenge.", + icon: "warning", + showCancelButton: true, + confirmButtonColor: "#e3342f", + cancelButtonColor: "#6b7280", + confirmButtonText: "Oui, dévalider", + cancelButtonText: "Annuler", + }); + + if (!confirm.isConfirmed) return; + + try { + const result = await unvalidateChallenge({ challengeId, factionId, teamId, userId }); + Swal.fire("Succès", result.message, "success"); + fetchValidatedChallenges(); + } catch { + Swal.fire("Erreur", "❌ Une erreur est survenue lors de la dévalidation", "error"); + } + }; + + return ( +
+
+

📋 Challenges validés

+ + {validatedChallenges.length === 0 ? ( +

Aucun challenge validé pour le moment.

+ ) : ( +
+ {validatedChallenges.map((challenge) => ( +
+
+
+

{challenge.challenge_name}

+

{challenge.challenge_categorie}

+

{challenge.challenge_description}

+
+ +
+

+ Points : {challenge.points} +

+

+ Validé le :{" "} + {new Date(challenge.validated_at).toLocaleDateString()} +

+
+
+ +
+
+

Destinataire :

+

{challenge.target_faction_name}

+

{challenge.target_team_name}

+

+ {challenge.target_user_firstname} {challenge.target_user_lastname} +

+
+ + +
+
+ ))} +
+ )} +
+
+ ); +}; diff --git a/frontend/src/components/Admin/AdminPerm/adminPermAction.tsx b/frontend/src/components/Admin/AdminPerm/adminPermAction.tsx new file mode 100644 index 0000000..e44ec01 --- /dev/null +++ b/frontend/src/components/Admin/AdminPerm/adminPermAction.tsx @@ -0,0 +1,87 @@ +import { Button } from "../../../components/ui/button"; +import Swal from "sweetalert2"; + +import { openPermanence, closePermanence } from "../../../services/requests/permanence.service"; +import { Permanence } from "../../../interfaces/permanence.interface"; + +interface PermanenceActionsProps { + permanences: Permanence[]; + onRefresh: () => void; +} + +// Fonction utilitaire pour "normaliser" une date au début de journée (00:00:00) +const normalizeDate = (d: Date): Date => { + return new Date(d.getFullYear(), d.getMonth(), d.getDate()); +}; + +const inSevenDays = (): Date => { + const d = new Date(); + d.setDate(d.getDate() + 7); + return normalizeDate(d); // → seuil à J+7 mais à 00h00 +}; + +const PermanenceActions: React.FC = ({ permanences, onRefresh }) => { + const handleOpenAll = async (): Promise => { + const confirm = await Swal.fire({ + title: "Ouvrir toutes à J+7 ?", + text: "Toutes les permanences commençant avant J+7 seront ouvertes.", + icon: "question", + showCancelButton: true, + confirmButtonText: "Ouvrir", + cancelButtonText: "Annuler", + }); + if (!confirm.isConfirmed) return; + + const threshold = inSevenDays().getTime(); + const toOpen = permanences.filter((p) => { + const permDate = normalizeDate(new Date(p.start_at)).getTime(); + return permDate <= threshold; + }); + + try { + await Promise.all(toOpen.map((p) => openPermanence(p.id))); + await Swal.fire("Ouvertes", "Toutes les permanences ont été ouvertes !", "success"); + onRefresh(); + } catch { + Swal.fire("Erreur", "Une erreur est survenue lors de l'ouverture", "error"); + } + }; + + const handleCloseAll = async (): Promise => { + const confirm = await Swal.fire({ + title: "Fermer toutes à J+7 ?", + text: "Toutes les permanences commençant avant J+7 seront fermées.", + icon: "warning", + showCancelButton: true, + confirmButtonText: "Fermer", + cancelButtonText: "Annuler", + }); + if (!confirm.isConfirmed) return; + + const threshold = inSevenDays().getTime(); + const toClose = permanences.filter((p) => { + const permDate = normalizeDate(new Date(p.start_at)).getTime(); + return permDate <= threshold; + }); + try { + await Promise.all(toClose.map((p) => closePermanence(p.id))); + await Swal.fire("Fermées", "Toutes les permanences ont été fermées !", "success"); + onRefresh(); + } catch { + Swal.fire("Erreur", "Une erreur est survenue lors de la fermeture", "error"); + } + }; + + return ( +
+ + +
+ ); +}; + +export default PermanenceActions; diff --git a/frontend/src/components/Admin/AdminPerm/adminPermForm.tsx b/frontend/src/components/Admin/AdminPerm/adminPermForm.tsx new file mode 100644 index 0000000..d68a57a --- /dev/null +++ b/frontend/src/components/Admin/AdminPerm/adminPermForm.tsx @@ -0,0 +1,220 @@ +import { useState, useEffect } from "react"; +import { Card } from "../../../components/ui/card"; +import { Input } from "../../../components/ui/input"; +import { Textarea } from "../../../components/ui/textarea"; +import { Button } from "../../../components/ui/button"; +import Select from "react-select"; +import Swal from "sweetalert2"; + +import { + createPermanence, + updatePermanence, +} from "../../../services/requests/permanence.service"; + +import { getUsers } from "../../../services/requests/user.service"; + +import { Permanence } from "../../../interfaces/permanence.interface"; +import { User } from "../../../interfaces/user.interface"; +import { formatDateForInput } from "../../utils/datetime_utils"; + +interface PermanenceFormProps { + editMode: boolean; + editPermanence: Permanence | null; + onRefresh: () => void; + onCancelEdit: () => void; +} + +const PermanenceForm = ({ + editMode, + editPermanence, + onRefresh, + onCancelEdit, +}: PermanenceFormProps) => { + const [name, setName] = useState(""); + const [desc, setDesc] = useState(""); + const [location, setLocation] = useState(""); + const [startAt, setStartAt] = useState(Date); + const [endAt, setEndAt] = useState(Date); + const [capacity, setCapacity] = useState(0); + const [difficulty, setDifficulty] = useState(0); + const [respo, setRespo] = useState(); + const [users, setUsers] = useState([]); + + useEffect(() => { + const fetchUsers = async () => { + try { + const data = await getUsers(); + setUsers(data); + } catch { + Swal.fire("Erreur", "Impossible de charger les utilisateurs", "error"); + } + }; + + fetchUsers(); + }, []); + + useEffect(() => { + if (editMode && editPermanence) { + setName(editPermanence.name); + setDesc(editPermanence.description); + setLocation(editPermanence.location); + setStartAt(formatDateForInput(editPermanence.start_at)); + setEndAt(formatDateForInput(editPermanence.end_at)); + setCapacity(editPermanence.capacity); + setDifficulty(editPermanence.difficulty); + if (editPermanence.respo) { + setRespo(editPermanence.respo); + } + } + }, [editMode, editPermanence]); + + const handleSubmit = async () => { + if ( + !name || + !desc || + !location || + !startAt || + !endAt || + !capacity || + !difficulty + ) { + Swal.fire("Erreur", "Veuillez remplir tous les champs", "warning"); + return; + } + + const respoId = + respo && !isNaN(Number(respo.userId)) ? Number(respo.userId) : null; + + try { + const payload = { + name, + description: desc, + location, + start_at: formatDateForInput(startAt), + end_at: formatDateForInput(endAt), + capacity, + difficulty, + respoId, + }; + + if (editMode && editPermanence) { + await updatePermanence(editPermanence.id, payload); + Swal.fire("Succès", "Permanence mise à jour", "success"); + onCancelEdit(); + } else { + await createPermanence(payload); + Swal.fire("Succès", "Permanence créée", "success"); + } + + resetForm(); + onRefresh(); + } catch (err: any) { + Swal.fire("Erreur", err.response.data.message, "error"); + } + }; + + const resetForm = () => { + setName(""); + setDesc(""); + setLocation(""); + setStartAt(""); + setEndAt(""); + setCapacity(0); + setDifficulty(0); + setRespo(null); + }; + + const respoOptions = users.map((user) => ({ + value: user.userId, + label: `${user.firstName} ${user.lastName}`, + })); + + const selectedRespoOption = respo + ? { value: respo.userId, label: `${respo.firstName} ${respo.lastName}` } + : null; + + return ( + +
+ setName(e.target.value)} + /> +