From 128ab6662e3a2d0ed08076b5b4adf9e9b8d34e90 Mon Sep 17 00:00:00 2001 From: "C. Fuhrman" Date: Thu, 3 Apr 2025 14:51:42 -0400 Subject: [PATCH] Trying context in JoinRoom --- client/package-lock.json | 52 ++--- .../TrueFalseQuestionDisplay.test.tsx | 116 +++++----- .../QuestionsDisplay/QuestionDisplay.tsx | 2 +- .../TrueFalseQuestionDisplay.tsx | 147 ++++++++----- .../StudentModeQuiz/StudentModeQuiz.tsx | 103 +++++---- .../src/pages/Student/JoinRoom/JoinRoom.tsx | 15 +- .../pages/Student/JoinRoom/QuizContext.tsx | 18 ++ .../pages/Student/JoinRoom/QuizProvider.tsx | 19 ++ server/package-lock.json | 199 ++++-------------- server/package.json | 2 +- 10 files changed, 315 insertions(+), 358 deletions(-) create mode 100644 client/src/pages/Student/JoinRoom/QuizContext.tsx create mode 100644 client/src/pages/Student/JoinRoom/QuizProvider.tsx diff --git a/client/package-lock.json b/client/package-lock.json index e2c6890..a8af949 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -419,26 +419,26 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", - "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -1893,9 +1893,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", - "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1905,14 +1905,14 @@ } }, "node_modules/@babel/template": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", - "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" @@ -1946,9 +1946,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -5336,9 +5336,9 @@ } }, "node_modules/axios": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz", - "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -12911,9 +12911,9 @@ } }, "node_modules/vite": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", - "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", + "integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==", "license": "MIT", "dependencies": { "esbuild": "^0.25.0", diff --git a/client/src/__tests__/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.test.tsx b/client/src/__tests__/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.test.tsx index f79d1da..b7af62f 100644 --- a/client/src/__tests__/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.test.tsx +++ b/client/src/__tests__/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.test.tsx @@ -1,40 +1,39 @@ -// TrueFalseQuestion.test.tsx -import React, { useState } from 'react'; +import React from 'react'; import { render, fireEvent, screen, act } from '@testing-library/react'; import '@testing-library/jest-dom'; import { MemoryRouter } from 'react-router-dom'; import TrueFalseQuestionDisplay from 'src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay'; import { parse, TrueFalseQuestion } from 'gift-pegjs'; import { AnswerType } from 'src/pages/Student/JoinRoom/JoinRoom'; +import { QuizProvider } from 'src/pages/Student/JoinRoom/QuizProvider'; +// import { useQuizContext } from 'src/pages/Student/JoinRoom/QuizContext'; -describe('TrueFalseQuestion Component', () => { +describe('TrueFalseQuestion Component with QuizContext', () => { const mockHandleSubmitAnswer = jest.fn(); const sampleStem = 'Sample True False Question'; const trueFalseQuestion = parse(`${sampleStem}{T}`)[0] as TrueFalseQuestion; - - - const TestWrapper = ({ showAnswer }: { showAnswer: boolean }) => { - const [showAnswerState, setShowAnswerState] = useState(showAnswer); - + + const TestWrapper = () => { const handleOnSubmitAnswer = (answer: AnswerType) => { mockHandleSubmitAnswer(answer); - setShowAnswerState(true); + // setShowAnswer(true); // set it in the context }; return ( - - - + + + + + ); }; beforeEach(() => { - render(); + render(); }); it('renders correctly', () => { @@ -89,49 +88,48 @@ describe('TrueFalseQuestion Component', () => { mockHandleSubmitAnswer.mockClear(); }); + it('should show ✅ next to the correct answer and ❌ next to the wrong answers when showAnswer is true', async () => { + const trueButton = screen.getByText('Vrai').closest('button'); + if (!trueButton) throw new Error('True button not found'); - it('should show ✅ next to the correct answer and ❌ next to the wrong answers when showAnswer is true', async () => { - const choiceButton = screen.getByText('Vrai').closest('button'); - if (!choiceButton) throw new Error('T button not found'); - - // Click on choiceButton - act(() => { - fireEvent.click(choiceButton); - }); - - const button = screen.getByText("Répondre"); - - act(() => { - fireEvent.click(button); - }); - - // Wait for the DOM to update - const correctAnswer = screen.getByText("Vrai").closest('button'); - expect(correctAnswer).toBeInTheDocument(); - expect(correctAnswer?.textContent).toContain('✅'); - - const wrongAnswer1 = screen.getByText("Faux").closest('button'); - expect(wrongAnswer1).toBeInTheDocument(); - expect(wrongAnswer1?.textContent).toContain('❌'); + // Click on trueButton + act(() => { + fireEvent.click(trueButton); }); - - it('should not show ✅ or ❌ when Répondre button is not clicked', async () => { - const choiceButton = screen.getByText('Vrai').closest('button'); - if (!choiceButton) throw new Error('Choice button not found'); - - // Click on choiceButton - act(() => { - fireEvent.click(choiceButton); - }); - - // Check for correct answer - const correctAnswer = screen.getByText("Vrai").closest('button'); - expect(correctAnswer).toBeInTheDocument(); - expect(correctAnswer?.textContent).not.toContain('✅'); - - // Check for wrong answers - const wrongAnswer1 = screen.getByText("Faux"); - expect(wrongAnswer1).toBeInTheDocument(); - expect(wrongAnswer1?.textContent).not.toContain('❌'); + + const submitButton = screen.getByText('Répondre'); + + act(() => { + fireEvent.click(submitButton); }); + + // Wait for the DOM to update + const correctAnswer = screen.getByText('Vrai').closest('button'); + expect(correctAnswer).toBeInTheDocument(); + expect(correctAnswer?.textContent).toContain('✅'); + + const wrongAnswer = screen.getByText('Faux').closest('button'); + expect(wrongAnswer).toBeInTheDocument(); + expect(wrongAnswer?.textContent).toContain('❌'); + }); + + it('should not show ✅ or ❌ when Répondre button is not clicked', async () => { + const trueButton = screen.getByText('Vrai').closest('button'); + if (!trueButton) throw new Error('True button not found'); + + // Click on trueButton + act(() => { + fireEvent.click(trueButton); + }); + + // Check for correct answer + const correctAnswer = screen.getByText('Vrai').closest('button'); + expect(correctAnswer).toBeInTheDocument(); + expect(correctAnswer?.textContent).not.toContain('✅'); + + // Check for wrong answers + const wrongAnswer = screen.getByText('Faux').closest('button'); + expect(wrongAnswer).toBeInTheDocument(); + expect(wrongAnswer?.textContent).not.toContain('❌'); + }); }); diff --git a/client/src/components/QuestionsDisplay/QuestionDisplay.tsx b/client/src/components/QuestionsDisplay/QuestionDisplay.tsx index af6e6d8..700f315 100644 --- a/client/src/components/QuestionsDisplay/QuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/QuestionDisplay.tsx @@ -33,7 +33,7 @@ const QuestionDisplay: React.FC = ({ ); diff --git a/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx b/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx index 717cdbe..5e0abe0 100644 --- a/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx +++ b/client/src/components/QuestionsDisplay/TrueFalseQuestionDisplay/TrueFalseQuestionDisplay.tsx @@ -5,24 +5,25 @@ import { Button } from '@mui/material'; import { TrueFalseQuestion } from 'gift-pegjs'; import { FormattedTextTemplate } from 'src/components/GiftTemplate/templates/TextTypeTemplate'; import { AnswerType } from 'src/pages/Student/JoinRoom/JoinRoom'; +import { QuizContext } from 'src/pages/Student/JoinRoom/QuizContext'; interface Props { question: TrueFalseQuestion; handleOnSubmitAnswer?: (answer: AnswerType) => void; - showAnswer?: boolean; + // showAnswer?: boolean; passedAnswer?: AnswerType; } const TrueFalseQuestionDisplay: React.FC = (props) => { - const { question, showAnswer, handleOnSubmitAnswer, passedAnswer } = + const { question, + // showAnswer, + handleOnSubmitAnswer, passedAnswer } = props; const [answer, setAnswer] = useState(() => { - if (passedAnswer && (passedAnswer[0] === true || passedAnswer[0] === false)) { return passedAnswer[0]; } - return undefined; }); @@ -31,6 +32,8 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { disableButton = true; } + + useEffect(() => { console.log("passedAnswer", passedAnswer); if (passedAnswer && (passedAnswer[0] === true || passedAnswer[0] === false)) { @@ -46,63 +49,99 @@ const TrueFalseQuestionDisplay: React.FC = (props) => { const selectedTrue = answer ? 'selected' : ''; const selectedFalse = answer !== undefined && !answer ? 'selected' : ''; + return ( -
-
-
-
-
- + +
+ {question.formattedGlobalFeedback && showAnswer && ( +
+
)} - - )} - -
- {question.formattedGlobalFeedback && showAnswer && ( -
-
)} - {!showAnswer && handleOnSubmitAnswer && ( - - )} -
+ ); }; diff --git a/client/src/components/StudentModeQuiz/StudentModeQuiz.tsx b/client/src/components/StudentModeQuiz/StudentModeQuiz.tsx index 192c0b2..1399881 100644 --- a/client/src/components/StudentModeQuiz/StudentModeQuiz.tsx +++ b/client/src/components/StudentModeQuiz/StudentModeQuiz.tsx @@ -4,11 +4,11 @@ import QuestionComponent from '../QuestionsDisplay/QuestionDisplay'; import '../../pages/Student/JoinRoom/joinRoom.css'; import { QuestionType } from '../../Types/QuestionType'; import { Button } from '@mui/material'; -//import QuestionNavigation from '../QuestionNavigation/QuestionNavigation'; import DisconnectButton from 'src/components/DisconnectButton/DisconnectButton'; import { Question } from 'gift-pegjs'; import { AnswerSubmissionToBackendType } from 'src/services/WebsocketService'; import { AnswerType } from 'src/pages/Student/JoinRoom/JoinRoom'; +import { useQuizContext } from 'src/pages/Student/JoinRoom/QuizContext'; interface StudentModeQuizProps { questions: QuestionType[]; @@ -23,21 +23,21 @@ const StudentModeQuiz: React.FC = ({ submitAnswer, disconnectWebSocket }) => { - //Ajouter type AnswerQuestionType en remplacement de QuestionType + const { setShowAnswer } = useQuizContext(); // Access setShowAnswer from context + const [questionInfos, setQuestion] = useState(questions[0]); const [isAnswerSubmitted, setIsAnswerSubmitted] = useState(false); - // const [answer, setAnswer] = useState(''); - const previousQuestion = () => { - setQuestion(questions[Number(questionInfos.question?.id) - 2]); + setQuestion(questions[Number(questionInfos.question?.id) - 2]); }; useEffect(() => { - const savedAnswer = answers[Number(questionInfos.question.id)-1]?.answer; + const savedAnswer = answers[Number(questionInfos.question.id) - 1]?.answer; console.log(`StudentModeQuiz: useEffect: savedAnswer: ${savedAnswer}`); setIsAnswerSubmitted(savedAnswer !== undefined); - }, [questionInfos.question, answers]); + setShowAnswer(savedAnswer !== undefined); // Update showAnswer in context + }, [questionInfos.question, answers, setShowAnswer]); const nextQuestion = () => { setQuestion(questions[Number(questionInfos.question?.id)]); @@ -47,60 +47,53 @@ const StudentModeQuiz: React.FC = ({ const idQuestion = Number(questionInfos.question.id) || -1; submitAnswer(answer, idQuestion); setIsAnswerSubmitted(true); + setShowAnswer(true); // Update showAnswer in context when an answer is submitted }; return ( -
-
- - -
-
- Question {questionInfos.question.id}/{questions.length} -
-
-
-
- {/* */} -
- -
-
- -
-
- -
+
+
+
+
+ Question {questionInfos.question.id}/{questions.length} +
+
+
+ +
+
+ +
+
+ +
+
+
-
); }; diff --git a/client/src/pages/Student/JoinRoom/JoinRoom.tsx b/client/src/pages/Student/JoinRoom/JoinRoom.tsx index a5ee1ff..e76c8c3 100644 --- a/client/src/pages/Student/JoinRoom/JoinRoom.tsx +++ b/client/src/pages/Student/JoinRoom/JoinRoom.tsx @@ -16,6 +16,7 @@ import LoadingButton from '@mui/lab/LoadingButton'; import LoginContainer from 'src/components/LoginContainer/LoginContainer' import ApiService from '../../../services/ApiService' +import { QuizProvider } from './QuizProvider'; export type AnswerType = Array; @@ -177,12 +178,14 @@ const JoinRoom: React.FC = () => { switch (quizMode) { case 'student': return ( - + + + ); case 'teacher': return ( diff --git a/client/src/pages/Student/JoinRoom/QuizContext.tsx b/client/src/pages/Student/JoinRoom/QuizContext.tsx new file mode 100644 index 0000000..84df990 --- /dev/null +++ b/client/src/pages/Student/JoinRoom/QuizContext.tsx @@ -0,0 +1,18 @@ +import React, { Dispatch, SetStateAction, useContext } from 'react'; + + +export const QuizContext = React.createContext<{ + showAnswer: boolean; + setShowAnswer: Dispatch>; + }>({ + showAnswer: false, + setShowAnswer: () => {}, + }); + +export const useQuizContext = () => { + const context = useContext(QuizContext); + if (!context) { + throw new Error('useQuizContext must be used within a QuizProvider'); + } + return context; +}; diff --git a/client/src/pages/Student/JoinRoom/QuizProvider.tsx b/client/src/pages/Student/JoinRoom/QuizProvider.tsx new file mode 100644 index 0000000..152e495 --- /dev/null +++ b/client/src/pages/Student/JoinRoom/QuizProvider.tsx @@ -0,0 +1,19 @@ +import React, { useEffect, useState } from 'react'; +import { QuizContext } from './QuizContext'; + +export const QuizProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + // State for showing answers + const [showAnswer, setShowAnswer] = useState(false); + + console.log('QuizProvider: showAnswer:', showAnswer); + + useEffect(() => { + console.log('QuizProvider: showAnswer:', showAnswer); + }, [showAnswer]); + + return ( + + {children} + + ); +}; diff --git a/server/package-lock.json b/server/package-lock.json index 0f006f8..95e76d8 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -55,68 +55,20 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@babel/compat-data": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", @@ -342,19 +294,21 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -369,88 +323,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", - "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@babel/parser": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", - "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.0" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -636,14 +530,15 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" @@ -704,14 +599,14 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", - "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -4772,7 +4667,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", @@ -6683,15 +6579,6 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/server/package.json b/server/package.json index cd0348b..3f0cfd4 100644 --- a/server/package.json +++ b/server/package.json @@ -42,7 +42,7 @@ "supertest": "^6.3.4" }, "engines": { - "node": "20.x" + "node": "22.x" }, "jest": { "testEnvironment": "node",