diff --git a/.gitignore b/.gitignore index d46849a..98b445c 100644 --- a/.gitignore +++ b/.gitignore @@ -113,3 +113,5 @@ docs/build/ # OLD DATABASE, DO NOT PUSH, IT CONTAINS SENSITIVE DATA migration/etuutt_old/etuutt_old.sql +# UE Data +scripts/**/*.csv \ No newline at end of file diff --git a/docs/doc_developers/api/index.md b/docs/doc_developers/api/index.md index 1458b47..f2a6a36 100644 --- a/docs/doc_developers/api/index.md +++ b/docs/doc_developers/api/index.md @@ -10,6 +10,6 @@ setup.md technologies.md conventions.md test.md +ues.md timetables.md ``` - diff --git a/docs/doc_developers/api/ues.md b/docs/doc_developers/api/ues.md new file mode 100644 index 0000000..1ca9cef --- /dev/null +++ b/docs/doc_developers/api/ues.md @@ -0,0 +1,72 @@ +# Le Guide des UEs + +_Avant la rentrée A24, la refonte du SIEP et par la même occasion la création du nouveau site étudiant, les UEs à l'UTT correspondaient à tous les différents cours donnés à l'UTT et dans ses antennes à Reims et Nogent. Ainsi, MT03 et MT03A (algèbre linéaire et algèbre linéaire en anglais) étaient deux UEs différentes. Avec cette refonte, a été introduite une distinction entre les cours et leurs variantes. Par exemple MT03A est en réalité une variante de MT03 et un étudiant n'est pas *censé* faire les deux. \ +Cette distinction entre les UEs (unité d'enseignement) et les UEOFs (offre de formation d'UE) permet ainsi de regrouper sous le même code d'UE deux cours différents sur la forme mais pas sur le fond. Pour s'adapter au mieux, le site étudiant a également adopté cette distinction, pour présenter au mieux les différentes opportunités en terme de cours disponibles tout en agrégeant les données utilisateur (commentaires, annales, notations, etc)_ + +## Glossaire : Les sigles made in UTT™ + +Avant tout, revenons rapidement sur les différentes abréviations qui figurent dans cette documentation et qui sont issues de l'admin de l'UTT : + +- **UE _(anciennement UV)_ :** unité d'enseignement. Un cours qui, une fois validé, certifie l'acquisition de commpétences particulières. Le code d'une UE est généralement composé d'un panachage de 4 chiffres et lettres, mais cette longueur n'est pas fixe. \ + Exemples : `NF10`, `MT01`, `APPTC` + > Certains codes d'UE ont changé pendant la refonte du SIEP, par exemple `PIX` est devenu `NF10`, `CTC1` est devenu `AST03`, ... +- **UEOF :** offre de formation d'UE. Il s'agit d'une version précise d'un cours avec un programme, une langue et un emplacement **fixes**. Ainsi en cas de modification de l'UE, de changement de programme ou encore de modification de la langue ou du lieu d'enseignement, une nouvelle UEOF sera crée. _Ces nouvelles considérations permettront au site étudiant d'évaluer l'ancienneté des programmes des UEs et de mieux pondérer les commentaires et notations._ Le code d'une UEOF est composé du code de l'UE, de la langue d'enseignement, du lieu d'enseignement ainsi que de son année de création. + Exemples : `NF10_FR_TRO_U24`, `MT01_FR_TRO_U23`, `APPTC_FR_TRO_U23` + > Attention, le concept d'UEOF n'existait pas avant 2023, donc les formations plus anciennes afficheront `U23` pour date de création ! +- **UEOE :** offre d'enseignement d'UE. L'enseignement d'une UEOF pendant un semestre précis. Ces codes apparaissent principalement sur le dossier étudiant et les emplois du temps. Ils sont constitués du début du code des UEOF avec le code de la période d'enseignement. Dans le site étudiant, les `UserUeSubscription` joueront le même rôle que les UEOE à la différence près qu'ils sont également rattachés à l'étudiant. \ + Exemples :`A24_NF10_FR_TRO`, `P25_MT01_FR_TRO`, `A24_APPTC_FR_TRO` +- **SIEP :** système informatique de l'enseignement et de la pédagogie. Le nouvel ERP de l'administration pour gérer les étudiants, leurs études et leurs données personnelles. Permet de centraliser tous les différents services qui existaient jusqu'à présent. \ + Cette nouvelle plateforme remplace ainsi de manière non-exhaustive : le guide des ues, le dossier étudiant, le suivi des stages et des alternances, les inscriptions et réinscriptions, les certificats de langue +- **DFP :** direction de la formation et de la pédagogie. L'équipe de l'UTT en charge de la formation et des outils administratifs (dont le SIEP fait partie) qui sont liés à la formation des étudiants. +- **ERP :** _en anglais, enterprise resource planning_. [Logiciel de gestion](https://fr.wikipedia.org/wiki/Progiciel_de_gestion_int%C3%A9gr%C3%A9) des processus et des ressources d'une entreprise. On peut retenir que c'est avant tout un logiciel de gestion, qui se décline dans le cadre du SIEP en une version incluant des pages web (celles du site du siep). Il faut bien retenir que le siep est avant tout un outil interne avant d'être un site internet ! Ainsi il ne faut pas compter sur de belles APIs propres... + +## Les UEs : La vision EtuUTT + +Depuis 2013 et avant, EtuUTT centralise les informations du guide des UEs, _qui rappelons-le était papier à ses débuts,_ et les enrichit de données supplémentaires : des ressentis d'anciens étudiants qui ont déjà suivi l'UE et des anciens sujets d'exams. Cela permet aux étudiants, aussi bien de choisir au mieux leurs prochains cours que de s'entrainer et réviser pour leurs examens. + +C'est dans cet état d'esprit que nous menons la refonte du site étudiant : + +- les commentaires sont toujours présents et permettent aux étudiants de s'exprimer librement sur leurs cours passés. + > Ces commentaires sont bien entendu **modérés** et ne sont visibles que par les étudiants (et anciens étudiants). \ + > ⚠️ Il faudra impérativement **avoir fait l'UE** pour pouvoir laisser un commentaire. Si un étudiant crée sont compte EtuUTT après le semestre où il a suivi l'UE1, il ne pourra pas s'exprimer sur cette UE. +- les utilisateurs peuvent désormais réagir à un commentaire d'UE en y répondant. Cela peut permettre de nuancer certains propos spécifiques ou au contraire de les développer par un argument supplémentaire ! +- les étudiants peuvent désormais _upvote_ les commentaires qui leurs semblent les plus pertinents. Ils remonteront dans la liste des commentaires. + > ❓ Les commentaires sont triés en fonction de leur nombre d'upvotes mais aussi de leur ancienneté et de l'UEOF à laquelle ils sont liés +- Pour que les étudiants donnent plus leur avis sur leurs cours, il est désormais possible de noter avec une note sur 5 les UEs déjà suivies1 sur des critères prédéfinis par les administrateurs. Il s'agira principalement d'évaluer la qualité des contenus et de l'enseignement. +- la recherche d'une UE affichera toutes les différentes version de l'UE (dans toutes ses langues d'enseignement et les différents semestres où elle est disponible). Les UEs sont désormais rattachées à aux branches au profil desquelles elles comptent. Cela permettra d'identifier facilement les UEs hors profil. +- les étudiants pourront consulter les anciens examens des UEs et partager ceux des semestres qu'ils ont suivi1. + +1 : il est possible qu'une importation du profil étudiant soit ajoutée dans le futur et qu'il soit ainsi possible de donner son avis sur des UEs suivies avant la création du compte EtuUTT. + +Les objectifs de la refonte du guide des UEs étant présentés, nous allons pouvoir aborder la partie technique. + +## Les structures + +Pour définir aux mieux les UEs, nous utilisons plusieurs structures de données. Passons-les en revue afin de comprendre l'usage de chacune d'elles : + +- **`Ue`**, il s'agit d'une UE au sens de la refonte du SIEP. C'est à dire qu'elle ne contient elle même que peu d'informations : sa date de création et de dernière modification ainsi que les notes des utilisateurs. Ce sont les `Ueof` liées à cette UE qui contiendront la majorité des détails du guide des UEs. +- **`UeAlias`**. Certaines UEs n'existent plus. C'est le cas de `MATH03` ou de `EC01` par exemple. Il faut donc gérer les cas où certaines UEs auraient des prérequis qui n'existent plus ! Pour des UEs qui ont changé de nom comme `MT03` il suffit de mettre en place une "redirection" et pour les UEs qui n'existent plus du tout comme `EC01` il faut également le notifier pour faire disparaître la référence. C'est tout l'intérêt de cette table. +- **`Ueof`**, c'est la structure qui définit une UEOF. Elle va donc être liée à toutes les informations du guide des UEs la concernant : temps de travail, crédits, branche associée, prérequis, commentaires, annales... Pour un soucis de lisibilité, cette structure n'inclut pas les données telles que la langue d'enseignement, les mineurs, le programme et les objectifs. On utilisera `UeofInfo` à la place. +- **`UeAnnal`**, il s'agit de la structure qui représente un sujet d'examen. Fait référence à l'utilisateur qui a envoyé le sujet, à l'UEOF, au semestre ainsi qu'au type d'examen (médian, final, etc) +- **`UeAnnalType`**, c'est le type d'examen d'une annale. Ces valeurs sont rentrées par les administrateurs du site qui seront dans la possibilité d'ajouter de nouveaux types d'examens s'ils se rendent compte que les valeurs précédentes ne sont pas assez précises. +- **`UeComment`**. Le commentaire d'un étudiant au sujet du cours qu'il a suivi. Ce commentaire est rattaché à l'UEOF correspondante afin d'afficher quelle variante de l'UE a été suivie mais sera affiché pour toutes les UEOFs de l'UE. Le commentaire peut être posté en anonyme mais l'auteur sera tout de même visible pour la modération. Egalement, les commentaires ne sont pas supprimés directement lorsque l'utilisateur choisit de les supprimer. Il y aura un petit délai permettant d'annuler la suppression ou de procéder à des actions de modération si nécessaire. +- **`UeCommentReply`**, c'est la réponse d'un utilisateur à un commentaire d'une UE. +- **`UeCommentUpvote`** il s'agit d'un upvote donné par n'importe quel étudiant à un commentaire de n'importe quelle UE s'il l'a trouvé instructif et/ou pertinent. +- **`UeCredit`**. C'est le nombre de crédits obtenus par un étudiant qui réalise l'UE. C'est ici qu'apparaît les branches et filières auxquelles cette UE est liée. En effet, il arrive qu'une même UE donne des crédits d'un type différent selon si l'étudiant est en master ou en cycle ingénieur. +- **`UeCreditCategory`**. Il s'agit des différents types de crédits ECTS: `CS`, `TM`, etc +- **`UeofInfo`**. C'est ici que figurent toutes les informations détaillées des UEOFs : leur programme, les objectifs, la langue d'enseignement, les mineurs, etc. Cela permet de ne pas surcharger la structure des UEOFs. +- **`UeStarCriterion`**. Les critères sur lesquels les utilisateurs peuvent évaluer une UE. Ces critères ne sont pas fixes et pourront être modifiés par les administrateurs du site s'ils se rendent compte qu'ils sont mal définis. +- **`UeStarVote`**, c'est le vote d'un utilisateur pour une UE donnée et un critère donné. Il ne peut y avoir qu'un seul vote par Utilisateur & Ue & Critère. +- **`UeWorkTime`**. Cette structure rassemble les heures de travail estimé pour effectuer l'UE. Il n'y a plus de nombre d'heures pour la réalisation d'un projet éventuel mais l'indication porte désormais sur le fait qu'il y ait un projet ou non. + +## Les Semestres + +La DFP a intégré certaines formations au guide des UEs qui n'ont pas lieu sur les semestres classiques d'automne et de printemps. Il a donc fallu intégrer de nouveaux laps de temps au site étudiant. Voici une correspondance entre les codes et leur signification : + +| Sigle | Signification | +| ----- | ----------------------------- | +| A24 | Semestre d'automne 2024 | +| P25 | Semestre de printemps 2025 | +| H25 | Intersemestre d'hiver 2025 | +| E25 | Intersemestre d'été 2025 | +| U24 | Année universitaire 2024-2025 | diff --git a/migration/etuutt_old/make-migration.ts b/migration/etuutt_old/make-migration.ts index c5657b9..28a8159 100644 --- a/migration/etuutt_old/make-migration.ts +++ b/migration/etuutt_old/make-migration.ts @@ -1,7 +1,7 @@ import { PrismaClient as _PrismaClient } from '@prisma/client'; import { createConnection } from 'mysql'; import { cleanDb } from '../../test/utils/test_utils'; -import { migrateUEs } from './modules/ue'; +import { findLegacyUeofName, migrateUEs } from './modules/ue'; import { createCreditCategories } from './modules/creditCategory'; import { createSemesters } from './modules/semester'; import { migrateUeComments } from './modules/ueComment'; @@ -15,7 +15,7 @@ import { RawUeComment, } from '../../src/prisma/types'; import { stringToTranslation } from './utils'; -import { omit, pick } from '../../src/utils'; +import { omit } from '../../src/utils'; type MayBePromise = Promise | T; @@ -33,6 +33,7 @@ export async function getOperationResults(operations: MayBePromise> { - const ue = await _prisma.ue.findUnique({ where: { code: params.code } }); + // Fix credit category types to match new categories + if (params.credits.category === 'HP' || params.credits.category === 'OTHER') params.credits.category = 'AC'; + if (params.credits.category === 'MASTER') params.credits.category = 'MA'; + const { ue: ueCode, ueof: ueofCode } = findLegacyUeofName(params.code, params.info.comment); + const ue = await _prisma.ue.findUnique({ where: { code: ueCode } }); if (!ue) { return { data: await _prisma.ue.create({ data: { - ...pick(params, 'code', 'inscriptionCode'), - name: stringToTranslation(params.name), - workTime: { - create: params.workTime, - }, - info: { - create: { - program: stringToTranslation(params.info.program), - objectives: stringToTranslation(params.info.objectives), - languages: params.info.languages, - minors: params.info.minors, - requirements: { - connect: params.info.requirements.map((value) => ({ id: value })), + code: ueCode, + ueofs: { + connectOrCreate: { + where: { + code: ueofCode, }, - comment: stringToTranslation(params.info.comment), - }, - }, - credits: { - create: { - credits: params.credits.credits, - category: { - connect: { - code: params.credits.category, + create: { + code: ueofCode, + siepId: ueId--, + available: false, + workTime: { + create: params.workTime, + }, + credits: { + create: { + credits: params.credits.credits, + category: { + connect: { + code: params.credits.category, + }, + }, + }, + }, + name: stringToTranslation(params.name), + info: { + create: { + program: stringToTranslation(params.info.program), + objectives: stringToTranslation(params.info.objectives), + language: params.info.languages, + minors: params.info.minors, + }, }, }, }, @@ -125,32 +136,38 @@ const prisma = _prisma.$extends({ // Ok that would be crazy to check every field, let's not do that return { data: await _prisma.ue.update({ - where: { code: params.code }, + where: { code: ueCode }, data: { - ...pick(params, 'code', 'inscriptionCode'), - name: stringToTranslation(params.name), - workTime: { - update: params.workTime, - }, - info: { - update: { - program: stringToTranslation(params.info.program), - objectives: stringToTranslation(params.info.objectives), - languages: params.info.languages, - minors: params.info.minors, - requirements: { - connect: params.info.requirements.map((value) => ({ id: value })), + ueofs: { + connectOrCreate: { + where: { + code: ueofCode, }, - comment: stringToTranslation(params.info.comment), - }, - }, - credits: { - deleteMany: {}, - create: { - credits: params.credits.credits, - category: { - connect: { - code: params.credits.category, + create: { + code: ueofCode, + siepId: ueId--, + available: false, + workTime: { + create: params.workTime, + }, + credits: { + create: { + credits: params.credits.credits, + category: { + connect: { + code: params.credits.category, + }, + }, + }, + }, + name: stringToTranslation(params.name), + info: { + create: { + program: stringToTranslation(params.info.program), + objectives: stringToTranslation(params.info.objectives), + language: params.info.languages, + minors: params.info.minors, + }, }, }, }, @@ -186,10 +203,12 @@ const prisma = _prisma.$extends({ async create({ code, name, + isMaster, description, }: { code: string; name: string; + isMaster: boolean; description: string; }): Promise> { const branch = await _prisma.uTTBranch.findUnique({ @@ -199,7 +218,7 @@ const prisma = _prisma.$extends({ if (!branch) { return { data: await _prisma.uTTBranch.create({ - data: { code, name, descriptionTranslation: stringToTranslation(description) }, + data: { code, name, isMaster, descriptionTranslation: stringToTranslation(description) }, }), operation: 'created', }; @@ -208,7 +227,7 @@ const prisma = _prisma.$extends({ return { data: await _prisma.uTTBranch.update({ where: { code }, - data: { name, descriptionTranslation: stringToTranslation(description) }, + data: { name, isMaster, descriptionTranslation: stringToTranslation(description) }, }), operation: 'updated', }; @@ -282,7 +301,13 @@ const prisma = _prisma.$extends({ ue: string; semesterCode: string; }): Promise> { - const comment = await _prisma.ueComment.findFirst({ where: { ue: { code: ue }, createdAt } }); + const codes = findLegacyUeofName(ue, ''); + // check this is the correct ueof : + let ueof = await _prisma.ueof.findFirst({ where: { code: codes.ueof } }); + if (!ueof) ueof = await _prisma.ueof.findFirst({ where: { code: codes.ueof.replace('TRO', 'REI') } }); + if (ueof) codes.ueof = codes.ueof.replace('TRO', 'REI'); + else console.error(`No such ueof for this code : ${codes.ueof}`); + const comment = await _prisma.ueComment.findFirst({ where: { ueof: { ue: { code: codes.ue } }, createdAt } }); if (!comment) { return { data: await _prisma.ueComment.create({ @@ -292,7 +317,7 @@ const prisma = _prisma.$extends({ createdAt, updatedAt, validatedAt: isValid ? updatedAt : null, - ue: { connect: { code: ue } }, + ueof: { connect: { code: codes.ueof } }, semester: { connect: { code: semesterCode } }, }, }), diff --git a/migration/etuutt_old/modules/branch.ts b/migration/etuutt_old/modules/branch.ts index 8cc3a89..b5280b2 100644 --- a/migration/etuutt_old/modules/branch.ts +++ b/migration/etuutt_old/modules/branch.ts @@ -9,12 +9,18 @@ export async function createBranches(prisma: PrismaClient) { TC(prisma), A2I(prisma), GI(prisma), + GI_APPR(prisma), GM(prisma), + GM_APPR(prisma), ISI(prisma), MTE(prisma), MM(prisma), RT(prisma), - SN(prisma), + SN_APPR(prisma), + RE(prisma), + PAIP(prisma), + ISC(prisma), + IC(prisma), ]; const operationsAwaited = await Promise.all(operations); const branchOptions = await getOperationResults(operationsAwaited.map(({ branchOptions }) => branchOptions).flat(1)); @@ -30,16 +36,17 @@ export async function createBranches(prisma: PrismaClient) { function TC(prisma: PrismaClient) { return prisma.uTTBranch .create({ - code: 'TCBR', - name: 'TCBR', + code: 'TC', + name: 'Tronc commun', + isMaster: false, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR_TC', - name: 'TCBR', + code: 'TC', + name: 'Tronc commun', description: '', branchCode: branch.data.code, }), @@ -52,20 +59,15 @@ function A2I(prisma: PrismaClient) { .create({ code: 'A2I', name: 'Automatique et Informatique Industrielle', + isMaster: false, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'TCBR', - description: '', - branchCode: branch.data.code, - }), - prisma.uTTBranchOption.create({ - code: 'LIBRE', - name: 'Filière LIBRE A2I', + code: 'A2I', + name: "Tronc commun d'Automatique et informatique industrielle", description: '', branchCode: branch.data.code, }), @@ -90,14 +92,15 @@ function GI(prisma: PrismaClient) { .create({ code: 'GI', name: 'Génie Industriel', + isMaster: false, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'Tronc commun de branche', + code: 'GI', + name: 'Tronc commun de Génie Industriel', description: '', branchCode: branch.data.code, }), @@ -119,6 +122,45 @@ function GI(prisma: PrismaClient) { description: '', branchCode: branch.data.code, }), + prisma.uTTBranchOption.create({ + code: 'LET_APPR', + name: 'Logistique Externe et Transport - Apprentissage', + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'LIP_APPR', + name: 'Logistique Interne et Production - Apprentissage', + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'RAMS_APPR', + name: 'Reliability, Availability, Maintenance and Safety - Apprentissage', + description: '', + branchCode: branch.data.code, + }), + ], + })); +} + +function GI_APPR(prisma: PrismaClient) { + return prisma.uTTBranch + .create({ + code: 'GI_APPR', + name: 'Génie Industriel - Apprentissage', + isMaster: false, + description: '', + }) + .then((branch) => ({ + branch, + branchOptions: [ + prisma.uTTBranchOption.create({ + code: 'GI_APPR', + name: 'Tronc commun de Génie Industriel - Apprentissage', + description: '', + branchCode: branch.data.code, + }), ], })); } @@ -127,15 +169,16 @@ function GM(prisma: PrismaClient) { return prisma.uTTBranch .create({ code: 'GM', - name: 'Génie Mécanique', + name: 'Génie Mécanique - Apprentissage', + isMaster: false, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'Tronc commun de branche', + code: 'GM', + name: 'Tronc commun de Génie Mécanique', description: '', branchCode: branch.data.code, }), @@ -151,6 +194,12 @@ function GM(prisma: PrismaClient) { description: '', branchCode: branch.data.code, }), + prisma.uTTBranchOption.create({ + code: 'MDPI_APPR', + name: 'Management Digital des Produits et Infrastructures - Apprentissage', + description: '', + branchCode: branch.data.code, + }), prisma.uTTBranchOption.create({ code: 'SNM', name: 'Simulation Numérique en Mécanique', @@ -161,19 +210,41 @@ function GM(prisma: PrismaClient) { })); } +function GM_APPR(prisma: PrismaClient) { + return prisma.uTTBranch + .create({ + code: 'GM_APPR', + name: 'Génie Mécanique', + isMaster: false, + description: '', + }) + .then((branch) => ({ + branch, + branchOptions: [ + prisma.uTTBranchOption.create({ + code: 'GM_APPR', + name: 'Tronc commun de Génie mécanique - Apprentissage', + description: '', + branchCode: branch.data.code, + }), + ], + })); +} + function ISI(prisma: PrismaClient) { return prisma.uTTBranch .create({ code: 'ISI', name: "Informatique et Systèmes d'Information", + isMaster: false, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'Tronc commun de branche', + code: 'ISI', + name: "Tronc commun d'Informatique et Systèmes d'Information", description: '', branchCode: branch.data.code, }), @@ -204,14 +275,15 @@ function MTE(prisma: PrismaClient) { .create({ code: 'MTE', name: 'Matériaux : Technologie et Economie', + isMaster: false, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'Tronc commun de branche', + code: 'MTE', + name: 'Tronc commun de Matériaux: Technologie et Economie', description: '', branchCode: branch.data.code, }), @@ -222,7 +294,7 @@ function MTE(prisma: PrismaClient) { branchCode: branch.data.code, }), prisma.uTTBranchOption.create({ - code: 'AUTO', + code: 'TCMC', name: 'Technologie et Commerce des Matériaux et des Composants', description: '', branchCode: branch.data.code, @@ -242,14 +314,15 @@ function MM(prisma: PrismaClient) { .create({ code: 'MM', name: 'Matériaux et Mécanique', + isMaster: false, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'Tronc commun de branche', + code: 'MM', + name: 'Tronc commun de Matériaux et Mécanique', description: '', branchCode: branch.data.code, }), @@ -263,13 +336,14 @@ function RT(prisma: PrismaClient) { code: 'RT', name: 'Réseaux et Télécommunications', description: '', + isMaster: false, }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'Tronc commun de branche', + code: 'RT', + name: 'Tronc commun de Réseaux et télécommunications', description: '', branchCode: branch.data.code, }), @@ -295,19 +369,146 @@ function RT(prisma: PrismaClient) { })); } -function SN(prisma: PrismaClient) { +function SN_APPR(prisma: PrismaClient) { + return prisma.uTTBranch + .create({ + code: 'SN_APPR', + name: 'Systèmes Numériques - Apprentissage', + isMaster: false, + description: '', + }) + .then((branch) => ({ + branch, + branchOptions: [ + prisma.uTTBranchOption.create({ + code: 'SN_APPR', + name: 'Tronc commun de Systèmes Numériques - Apprentissage', + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'SN', + name: 'Tronc commun de Systèmes Numériques', + description: '', + branchCode: branch.data.code, + }), + ], + })); +} + +function RE(prisma: PrismaClient) { + return prisma.uTTBranch + .create({ + code: 'RE', + name: 'Risques et Environnement', + isMaster: true, + description: '', + }) + .then((branch) => ({ + branch, + branchOptions: [ + prisma.uTTBranchOption.create({ + code: 'RE', + name: 'Mention Risques et Environnement', + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'IMEDD', + name: "Ingénierie et Management de l'Environnement et du Développement Durable", + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'IMSGA', + name: 'Ingénierie et Management en Sécurité Globale Appliquée', + description: '', + branchCode: branch.data.code, + }), + ], + })); +} + +function PAIP(prisma: PrismaClient) { + return prisma.uTTBranch + .create({ + code: 'PAIP', + name: 'Physique Appliquée et Ingénierie Physique', + isMaster: true, + description: '', + }) + .then((branch) => ({ + branch, + branchOptions: [ + prisma.uTTBranchOption.create({ + code: 'PAIP', + name: 'Mention Physique Appliquée et Ingénierie Physique', + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'NPHOT', + name: 'Nano-optics and Nanophotonics', + description: '', + branchCode: branch.data.code, + }), + ], + })); +} + +function ISC(prisma: PrismaClient) { return prisma.uTTBranch .create({ - code: 'SN', - name: 'Systèmes Numériques', + code: 'ISC', + name: 'Ingénierie des Systèmes Complexes', + isMaster: true, description: '', }) .then((branch) => ({ branch, branchOptions: [ prisma.uTTBranchOption.create({ - code: 'TCBR', - name: 'Tronc commun de branche', + code: 'ISC', + name: 'Mention Ingénierie des Systèmes Complexes', + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'SSI', + name: "Sécurité des Systèmes d'Information", + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'OSS', + name: 'Optimisation et Sûreté des Systèmes', + description: '', + branchCode: branch.data.code, + }), + ], + })); +} + +function IC(prisma: PrismaClient) { + return prisma.uTTBranch + .create({ + code: 'IC', + name: 'Ingénierie de Conception', + isMaster: true, + description: '', + }) + .then((branch) => ({ + branch, + branchOptions: [ + prisma.uTTBranchOption.create({ + code: 'IC', + name: 'Mention Ingénierie de Conception', + description: '', + branchCode: branch.data.code, + }), + prisma.uTTBranchOption.create({ + code: 'MPSMP', + name: 'Mécanique et Performance en Service de Matériaux et Produits', description: '', branchCode: branch.data.code, }), diff --git a/migration/etuutt_old/modules/creditCategory.ts b/migration/etuutt_old/modules/creditCategory.ts index 31193a7..c798550 100644 --- a/migration/etuutt_old/modules/creditCategory.ts +++ b/migration/etuutt_old/modules/creditCategory.ts @@ -3,42 +3,14 @@ import { RawCreditCategory } from '../../../src/prisma/types'; export async function createCreditCategories(prisma: PrismaClient) { const creditCategoriesData = [ - { - code: 'CS', - name: 'Connaissances scientifiques', - }, - { - code: 'TM', - name: 'Techniques et méthodes', - }, - { - code: 'EC', - name: 'Expression et communication', - }, - { - code: 'ME', - name: "Management de l'entreprise", - }, - { - code: 'HT', - name: 'Humanité et technologie', - }, - { - code: 'ST', - name: 'Stage', - }, - { - code: 'HP', - name: 'Hors profil', - }, - { - code: 'MASTER', - name: 'Master', - }, - { - code: 'OTHER', - name: 'Autre', - }, + { code: 'CS', name: 'Connaissances scientifiques' }, + { code: 'TM', name: 'Techniques et méthodes' }, + { code: 'ST', name: 'Stage' }, + { code: 'HT', name: 'Humanités et technologies' }, + { code: 'ME', name: 'Mise en situation' }, + { code: 'EC', name: 'Expression et communication' }, + { code: 'AC', name: 'Autres Crédits' }, + { code: 'MA', name: 'Master' }, ]; const operations: Promise>[] = []; for (const creditCategoryData of creditCategoriesData) { diff --git a/migration/etuutt_old/modules/ue.ts b/migration/etuutt_old/modules/ue.ts index 66c02bc..4dbdb53 100644 --- a/migration/etuutt_old/modules/ue.ts +++ b/migration/etuutt_old/modules/ue.ts @@ -2,6 +2,26 @@ import { getOperationResults, PrismaOperationResult, QueryFunction } from '../ma import { PrismaClient } from '../make-migration'; import { RawUe } from '../../../src/prisma/types'; +export function findLegacyUeofName(ueCode: string, comment: string) { + let LOCATION = 'TRO'; + if (comment.match(/UE réalisée à Reims/)) LOCATION = 'REI'; + let UECODE = ueCode; + let LANG = 'FR'; + if (ueCode.length > 4 && ueCode.slice(-1).match(/[APR]/)) { + const modifier = ueCode.slice(-1); + UECODE = ueCode.slice(0, -1); + if (modifier === 'A') LANG = 'EN'; + if (modifier === 'R') LOCATION = 'REI'; + } + if (ueCode.startsWith('LG')) LANG = 'GE'; + if (ueCode.startsWith('IT')) LANG = 'IT'; + if (ueCode.startsWith('KO')) LANG = 'KO'; + if (ueCode.startsWith('LC')) LANG = 'CH'; + if (ueCode.startsWith('LP')) LANG = 'PO'; + if (ueCode.startsWith('LS')) LANG = 'SP'; + return { ue: UECODE, ueof: `${UECODE}_${LANG}_${LOCATION}_LEG` }; +} + export async function migrateUEs(query: QueryFunction, prisma: PrismaClient) { const ues = await query('SELECT * FROM etu_uvs WHERE isOld = 0'); const operations: PrismaOperationResult[] = []; @@ -12,34 +32,17 @@ export async function migrateUEs(query: QueryFunction, prisma: PrismaClient) { ? -1 : 0, ); - const inscriptionCodes: string[] = (await prisma.ue.findMany({ select: { inscriptionCode: true } })).map( - ({ inscriptionCode }) => inscriptionCode, - ); for (const ue of ues) { - let inscriptionCode = ue.code.slice(0, 4); - while (inscriptionCodes.includes(inscriptionCode)) { - inscriptionCode = - inscriptionCode.slice(0, 3) + - Math.floor(Math.random() * 36) - .toString(36) - .toUpperCase(); - } - inscriptionCodes.push(inscriptionCode); - const requirements = operations - .filter((u) => new RegExp(`(^|\\W)${u.data.code}($|\\W)`).test(ue.antecedents)) - .map((u) => u.data.id); - //console.log(ue.code, inscriptionCode); operations.push( await prisma.ue.create({ code: ue.code, name: ue.name, - inscriptionCode, workTime: { cm: ue.cm, td: ue.td, tp: ue.tp, the: ue.the, - project: ue.projet, + project: ue.projet > 0, internship: ue.stage, }, info: { @@ -47,7 +50,6 @@ export async function migrateUEs(query: QueryFunction, prisma: PrismaClient) { objectives: ue.objectifs, languages: ue.languages, minors: ue.mineurs, - requirements, comment: ue.commentaire, }, credits: { @@ -59,5 +61,32 @@ export async function migrateUEs(query: QueryFunction, prisma: PrismaClient) { } const results = await getOperationResults(operations); console.log(`UEs : created ${results.created}, updated ${results.updated}, not changed ${results.notChanged}`); + let linkingOperations = 0; + for (const ue of ues) { + const { ue: ueCode, ueof: ueofCode } = findLegacyUeofName(ue.code, ue.commentaire); + const requirements = operations + .filter((u) => new RegExp(`(^|\\W)${u.data.code}($|\\W)`).test(ue.antecedents)) + .map((u) => u.data.code); + if (requirements.length === 0) continue; + linkingOperations++; + prisma.ue.update({ + where: { code: ueCode }, + data: { + ueofs: { + update: { + where: { + code: ueofCode, + }, + data: { + requirements: { + connect: requirements.map((value) => ({ code: value })), + }, + }, + }, + }, + }, + }); + } + console.log(`UEs : linked ${linkingOperations}`); return results.data; } diff --git a/migration/etuutt_old/modules/user.ts b/migration/etuutt_old/modules/user.ts index 1cb6211..4450823 100644 --- a/migration/etuutt_old/modules/user.ts +++ b/migration/etuutt_old/modules/user.ts @@ -89,7 +89,7 @@ export async function migrateUsers( UesSubscriptions: { createMany: { data: user.uvs.split('|').map((code) => ({ - ueId: ues.find((ue) => ue.code === code).id, + ueId: ues.find((ue) => ue.code === code).code, semesterId: currentSemester.code, })), }, diff --git a/package.json b/package.json index e36f961..61753a6 100644 --- a/package.json +++ b/package.json @@ -25,39 +25,46 @@ "test:cov": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --coverage --config ./test/jest.json --runInBand", "test:instantfail": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --config test/jest.json --runInBand --testNamePattern --bail", "test:db:reset": "env-cmd -f .env.test --use-shell \"pnpm prisma migrate reset --force && pnpm prisma db push\"", - "test:db:editor": "env-cmd -f .env.test -- pnpm prisma studio" + "test:db:editor": "env-cmd -f .env.test -- pnpm prisma studio", + "seed:base": "env-cmd -f .env.dev -- ts-node scripts/seed/base.ts", + "seed:ue": "env-cmd -f .env.dev -- ts-node scripts/seed/ue.ts", + "seed:ue:aliases": "env-cmd -f .env.dev -- ts-node scripts/seed/aliases.ts", + "seed:base:prod": "node scripts/seed/base.js", + "seed:ue:prod": "node scripts/seed/ue.js", + "seed:ue:aliases:prod": "node scripts/seed/aliases.js" }, "dependencies": { + "@fast-csv/parse": "^5.0.0", "@nestjs/axios": "^3.0.2", - "@nestjs/common": "^10.3.0", - "@nestjs/config": "^3.1.1", - "@nestjs/core": "^10.3.0", + "@nestjs/common": "^10.3.10", + "@nestjs/config": "^3.2.3", + "@nestjs/core": "^10.3.10", "@nestjs/jwt": "^10.2.0", "@nestjs/passport": "^10.0.3", - "@nestjs/platform-express": "^10.3.0", - "@nestjs/swagger": "^7.2.0", - "@prisma/client": "^5.8.1", - "axios": "^1.6.7", + "@nestjs/platform-express": "^10.3.10", + "@nestjs/swagger": "^7.4.0", + "@prisma/client": "^5.17.0", + "axios": "^1.7.2", "bcryptjs": "^2.4.3", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", - "fast-xml-parser": "^4.3.6", - "file-type": "^19.0.0", - "ldapts": "^7.0.10", + "fast-xml-parser": "^4.4.0", + "file-type": "^19.2.0", + "ldapts": "^7.1.0", "multer": "1.4.5-lts.1", - "pactum-matchers": "^1.1.6", + "pactum-matchers": "^1.1.7", "passport-jwt": "^4.0.1", "pdfkit": "^0.14.0", - "prisma": "^5.8.1", + "prisma": "^5.17.0", "reflect-metadata": "^0.1.14", "rxjs": "^7.8.1", - "sharp": "^0.33.2" + "sharp": "^0.33.4" }, "devDependencies": { "@faker-js/faker": "^7.6.0", - "@nestjs/cli": "^10.3.0", - "@nestjs/schematics": "^10.1.0", - "@nestjs/testing": "^10.3.0", + "@nestjs/cli": "^10.4.2", + "@nestjs/schematics": "^10.1.2", + "@nestjs/testing": "^10.3.10", "@types/bcryptjs": "^2.4.6", "@types/express": "^4.17.21", "@types/jest": "29.5.0", @@ -70,14 +77,14 @@ "@typescript-eslint/parser": "^5.62.0", "cz-emoji": "1.3.2-canary.2", "env-cmd": "^10.1.0", - "eslint": "^8.56.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-prettier": "^4.2.1", "jest": "29.5.0", "ldap-server-mock": "^6.0.1", "mysql": "^2.18.1", "nock": "^13.5.4", - "pactum": "^3.6.0", + "pactum": "^3.7.0", "prettier": "^2.8.8", "source-map-support": "^0.5.21", "ts-jest": "29.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b63b9f..39ed627 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,36 +8,39 @@ importers: .: dependencies: + '@fast-csv/parse': + specifier: ^5.0.0 + version: 5.0.0 '@nestjs/axios': specifier: ^3.0.2 - version: 3.0.2(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(axios@1.6.7)(rxjs@7.8.1) + version: 3.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(axios@1.7.2)(rxjs@7.8.1) '@nestjs/common': - specifier: ^10.3.0 - version: 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + specifier: ^10.3.10 + version: 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/config': - specifier: ^3.1.1 - version: 3.1.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14) + specifier: ^3.2.3 + version: 3.2.3(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(rxjs@7.8.1) '@nestjs/core': - specifier: ^10.3.0 - version: 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + specifier: ^10.3.10 + version: 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/jwt': specifier: ^10.2.0 - version: 10.2.0(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)) + version: 10.2.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)) '@nestjs/passport': specifier: ^10.0.3 - version: 10.0.3(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(passport@0.6.0) + version: 10.0.3(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(passport@0.7.0) '@nestjs/platform-express': - specifier: ^10.3.0 - version: 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1) + specifier: ^10.3.10 + version: 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10) '@nestjs/swagger': - specifier: ^7.2.0 - version: 7.2.0(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14) + specifier: ^7.4.0 + version: 7.4.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14) '@prisma/client': - specifier: ^5.8.1 - version: 5.8.1(prisma@5.8.1) + specifier: ^5.17.0 + version: 5.17.0(prisma@5.17.0) axios: - specifier: ^1.6.7 - version: 1.6.7 + specifier: ^1.7.2 + version: 1.7.2 bcryptjs: specifier: ^2.4.3 version: 2.4.3 @@ -48,20 +51,20 @@ importers: specifier: ^0.14.1 version: 0.14.1 fast-xml-parser: - specifier: ^4.3.6 - version: 4.3.6 + specifier: ^4.4.0 + version: 4.4.0 file-type: - specifier: ^19.0.0 - version: 19.0.0 + specifier: ^19.2.0 + version: 19.2.0 ldapts: - specifier: ^7.0.10 - version: 7.0.12 + specifier: ^7.1.0 + version: 7.1.0 multer: specifier: 1.4.5-lts.1 version: 1.4.5-lts.1 pactum-matchers: - specifier: ^1.1.6 - version: 1.1.6 + specifier: ^1.1.7 + version: 1.1.7 passport-jwt: specifier: ^4.0.1 version: 4.0.1 @@ -69,8 +72,8 @@ importers: specifier: ^0.14.0 version: 0.14.0 prisma: - specifier: ^5.8.1 - version: 5.8.1 + specifier: ^5.17.0 + version: 5.17.0 reflect-metadata: specifier: ^0.1.14 version: 0.1.14 @@ -78,21 +81,21 @@ importers: specifier: ^7.8.1 version: 7.8.1 sharp: - specifier: ^0.33.2 - version: 0.33.2 + specifier: ^0.33.4 + version: 0.33.4 devDependencies: '@faker-js/faker': specifier: ^7.6.0 version: 7.6.0 '@nestjs/cli': - specifier: ^10.3.0 - version: 10.3.0 + specifier: ^10.4.2 + version: 10.4.2 '@nestjs/schematics': - specifier: ^10.1.0 - version: 10.1.0(chokidar@3.5.3)(typescript@4.9.5) + specifier: ^10.1.2 + version: 10.1.2(chokidar@3.6.0)(typescript@4.9.5) '@nestjs/testing': - specifier: ^10.3.0 - version: 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1)) + specifier: ^10.3.10 + version: 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10)) '@types/bcryptjs': specifier: ^2.4.6 version: 2.4.6 @@ -119,10 +122,10 @@ importers: version: 0.13.4 '@typescript-eslint/eslint-plugin': specifier: ^5.62.0 - version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@4.9.5))(eslint@8.56.0)(typescript@4.9.5) + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@4.9.5))(eslint@8.57.0)(typescript@4.9.5) '@typescript-eslint/parser': specifier: ^5.62.0 - version: 5.62.0(eslint@8.56.0)(typescript@4.9.5) + version: 5.62.0(eslint@8.57.0)(typescript@4.9.5) cz-emoji: specifier: 1.3.2-canary.2 version: 1.3.2-canary.2 @@ -130,14 +133,14 @@ importers: specifier: ^10.1.0 version: 10.1.0 eslint: - specifier: ^8.56.0 - version: 8.56.0 + specifier: ^8.57.0 + version: 8.57.0 eslint-config-prettier: specifier: ^8.10.0 - version: 8.10.0(eslint@8.56.0) + version: 8.10.0(eslint@8.57.0) eslint-plugin-prettier: specifier: ^4.2.1 - version: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.56.0))(eslint@8.56.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8) jest: specifier: 29.5.0 version: 29.5.0(@types/node@18.15.11)(ts-node@10.9.2(@types/node@18.15.11)(typescript@4.9.5)) @@ -151,8 +154,8 @@ importers: specifier: ^13.5.4 version: 13.5.4 pactum: - specifier: ^3.6.0 - version: 3.6.0 + specifier: ^3.7.0 + version: 3.7.0 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -161,10 +164,10 @@ importers: version: 0.5.21 ts-jest: specifier: 29.1.0 - version: 29.1.0(@babel/core@7.23.6)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.6))(jest@29.5.0(@types/node@18.15.11)(ts-node@10.9.2(@types/node@18.15.11)(typescript@4.9.5)))(typescript@4.9.5) + version: 29.1.0(@babel/core@7.24.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.5.0(@types/node@18.15.11)(ts-node@10.9.2(@types/node@18.15.11)(typescript@4.9.5)))(typescript@4.9.5) ts-loader: specifier: ^9.5.1 - version: 9.5.1(typescript@4.9.5)(webpack@5.89.0) + version: 9.5.1(typescript@4.9.5)(webpack@5.92.1) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@18.15.11)(typescript@4.9.5) @@ -177,16 +180,12 @@ importers: packages: - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - '@ampproject/remapping@2.2.1': - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular-devkit/core@17.0.9': - resolution: {integrity: sha512-r5jqwpWOgowqe9KSDqJ3iSbmsEt2XPjSvRG4DSI2T9s31bReoMtreo8b7wkRa2B3hbcDnstFbn8q27VvJDqRaQ==} + '@angular-devkit/core@17.3.8': + resolution: {integrity: sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==} engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: chokidar: ^3.5.2 @@ -194,95 +193,95 @@ packages: chokidar: optional: true - '@angular-devkit/schematics-cli@17.0.9': - resolution: {integrity: sha512-tznzzB26sy8jVUlV9HhXcbFYZcIIFMAiDMOuyLko2LZFjfoqW+OPvwa1mwAQwvVVSQZVAKvdndFhzwyl/axwFQ==} + '@angular-devkit/schematics-cli@17.3.8': + resolution: {integrity: sha512-TjmiwWJarX7oqvNiRAroQ5/LeKUatxBOCNEuKXO/PV8e7pn/Hr/BqfFm+UcYrQoFdZplmtNAfqmbqgVziKvCpA==} engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular-devkit/schematics@17.0.9': - resolution: {integrity: sha512-5ti7g45F2KjDJS0DbgnOGI1GyKxGpn4XsKTYJFJrSAWj6VpuvPy/DINRrXNuRVo09VPEkqA+IW7QwaG9icptQg==} + '@angular-devkit/schematics@17.3.8': + resolution: {integrity: sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==} engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} '@arr/every@1.0.1': resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==} engines: {node: '>=4'} - '@babel/code-frame@7.23.5': - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.23.5': - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + '@babel/compat-data@7.24.9': + resolution: {integrity: sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==} engines: {node: '>=6.9.0'} - '@babel/core@7.23.6': - resolution: {integrity: sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==} + '@babel/core@7.24.9': + resolution: {integrity: sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.23.6': - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + '@babel/generator@7.24.10': + resolution: {integrity: sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + '@babel/helper-compilation-targets@7.24.8': + resolution: {integrity: sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==} engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.22.15': - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.23.3': - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + '@babel/helper-module-transforms@7.24.9': + resolution: {integrity: sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.22.5': - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + '@babel/helper-plugin-utils@7.24.8': + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} engines: {node: '>=6.9.0'} - '@babel/helper-simple-access@7.22.5': - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.23.4': - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.22.20': - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.23.6': - resolution: {integrity: sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==} + '@babel/helpers@7.24.8': + resolution: {integrity: sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.23.4': - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.23.6': - resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + '@babel/parser@7.24.8': + resolution: {integrity: sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==} engines: {node: '>=6.0.0'} hasBin: true @@ -311,8 +310,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.23.3': - resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -353,22 +352,22 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.23.3': - resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/template@7.22.15': - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + '@babel/template@7.24.7': + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.23.6': - resolution: {integrity: sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==} + '@babel/traverse@7.24.8': + resolution: {integrity: sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.23.6': - resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + '@babel/types@7.24.9': + resolution: {integrity: sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -382,8 +381,8 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@emnapi/runtime@0.45.0': - resolution: {integrity: sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==} + '@emnapi/runtime@1.2.0': + resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} @@ -391,16 +390,16 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + '@eslint-community/regexpp@4.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@8.56.0': - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} '@exodus/schemasafe@1.3.0': @@ -410,126 +409,131 @@ packages: resolution: {integrity: sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==} engines: {node: '>=14.0.0', npm: '>=6.0.0'} - '@humanwhocodes/config-array@0.11.13': - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + '@fast-csv/parse@5.0.0': + resolution: {integrity: sha512-ecF8tCm3jVxeRjEB6VPzmA+1wGaJ5JgaUX2uesOXdXD6qQp0B3EdshOIed4yT1Xlj/F2f8v4zHSo0Oi31L697g==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.1': - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead - '@img/sharp-darwin-arm64@0.33.2': - resolution: {integrity: sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==} + '@img/sharp-darwin-arm64@0.33.4': + resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.33.2': - resolution: {integrity: sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==} + '@img/sharp-darwin-x64@0.33.4': + resolution: {integrity: sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.0.1': - resolution: {integrity: sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==} + '@img/sharp-libvips-darwin-arm64@1.0.2': + resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==} engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.0.1': - resolution: {integrity: sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==} + '@img/sharp-libvips-darwin-x64@1.0.2': + resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==} engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.0.1': - resolution: {integrity: sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==} + '@img/sharp-libvips-linux-arm64@1.0.2': + resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==} engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.0.1': - resolution: {integrity: sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==} + '@img/sharp-libvips-linux-arm@1.0.2': + resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==} engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-s390x@1.0.1': - resolution: {integrity: sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==} + '@img/sharp-libvips-linux-s390x@1.0.2': + resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==} engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.0.1': - resolution: {integrity: sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==} + '@img/sharp-libvips-linux-x64@1.0.2': + resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==} engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.0.1': - resolution: {integrity: sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==} + '@img/sharp-libvips-linuxmusl-arm64@1.0.2': + resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==} engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.0.1': - resolution: {integrity: sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==} + '@img/sharp-libvips-linuxmusl-x64@1.0.2': + resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==} engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.33.2': - resolution: {integrity: sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==} + '@img/sharp-linux-arm64@0.33.4': + resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.33.2': - resolution: {integrity: sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==} + '@img/sharp-linux-arm@0.33.4': + resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==} engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm] os: [linux] - '@img/sharp-linux-s390x@0.33.2': - resolution: {integrity: sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==} - engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + '@img/sharp-linux-s390x@0.33.4': + resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==} + engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.33.2': - resolution: {integrity: sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==} + '@img/sharp-linux-x64@0.33.4': + resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.33.2': - resolution: {integrity: sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==} + '@img/sharp-linuxmusl-arm64@0.33.4': + resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.33.2': - resolution: {integrity: sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==} + '@img/sharp-linuxmusl-x64@0.33.4': + resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.33.2': - resolution: {integrity: sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==} + '@img/sharp-wasm32@0.33.4': + resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [wasm32] - '@img/sharp-win32-ia32@0.33.2': - resolution: {integrity: sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==} + '@img/sharp-win32-ia32@0.33.4': + resolution: {integrity: sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.33.2': - resolution: {integrity: sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==} + '@img/sharp-win32-x64@0.33.4': + resolution: {integrity: sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [win32] @@ -612,38 +616,41 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} - '@jridgewell/resolve-uri@3.1.1': - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - '@jridgewell/source-map@0.3.5': - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/trace-mapping@0.3.20': - resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@ljharb/through@2.3.11': - resolution: {integrity: sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w==} + '@ljharb/through@2.3.13': + resolution: {integrity: sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==} engines: {node: '>= 0.4'} '@lukeed/csprng@1.1.0': resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} engines: {node: '>=8'} + '@microsoft/tsdoc@0.15.0': + resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} + '@nestjs/axios@3.0.2': resolution: {integrity: sha512-Z6GuOUdNQjP7FX+OuV2Ybyamse+/e0BFdTWBX5JxpBDKA+YkdLynDgG6HTF04zy6e9zPa19UX0WA2VDoehwhXQ==} peerDependencies: @@ -651,12 +658,12 @@ packages: axios: ^1.3.1 rxjs: ^6.0.0 || ^7.0.0 - '@nestjs/cli@10.3.0': - resolution: {integrity: sha512-37h+wSDItY0NE/x3a/M9yb2cXzfsD4qoE26rHgFn592XXLelDN12wdnfn7dTIaiRZT7WOCdQ+BYP9mQikR4AsA==} + '@nestjs/cli@10.4.2': + resolution: {integrity: sha512-fQexIfLHfp6GUgX+CO4fOg+AEwV5ox/LHotQhyZi9wXUQDyIqS0NTTbumr//62EcX35qV4nU0359nYnuEdzG+A==} engines: {node: '>= 16.14'} hasBin: true peerDependencies: - '@swc/cli': ^0.1.62 + '@swc/cli': ^0.1.62 || ^0.3.0 || ^0.4.0 '@swc/core': ^1.3.62 peerDependenciesMeta: '@swc/cli': @@ -664,12 +671,12 @@ packages: '@swc/core': optional: true - '@nestjs/common@10.3.1': - resolution: {integrity: sha512-YuxeIlVemVQCuXMkNbBpNlmwZgp/Cu6dwCOjki63mhyYHEFX48GNNA4zZn5MFRjF4h7VSceABsScROuzsxs9LA==} + '@nestjs/common@10.3.10': + resolution: {integrity: sha512-H8k0jZtxk1IdtErGDmxFRy0PfcOAUg41Prrqpx76DQusGGJjsaovs1zjXVD1rZWaVYchfT1uczJ6L4Kio10VNg==} peerDependencies: class-transformer: '*' class-validator: '*' - reflect-metadata: ^0.1.12 + reflect-metadata: ^0.1.12 || ^0.2.0 rxjs: ^7.1.0 peerDependenciesMeta: class-transformer: @@ -677,20 +684,20 @@ packages: class-validator: optional: true - '@nestjs/config@3.1.1': - resolution: {integrity: sha512-qu5QlNiJdqQtOsnB6lx4JCXPQ96jkKUsOGd+JXfXwqJqZcOSAq6heNFg0opW4pq4J/VZoNwoo87TNnx9wthnqQ==} + '@nestjs/config@3.2.3': + resolution: {integrity: sha512-p6yv/CvoBewJ72mBq4NXgOAi2rSQNWx3a+IMJLVKS2uiwFCOQQuiIatGwq6MRjXV3Jr+B41iUO8FIf4xBrZ4/w==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 - reflect-metadata: ^0.1.13 + rxjs: ^7.1.0 - '@nestjs/core@10.3.1': - resolution: {integrity: sha512-mh6FwTKh2R3CmLRuB50BF5q/lzc+Mz+7qAlEvpgCiTSIfSXzbQ47vWpfgLirwkL3SlCvtFS8onxOeI69RpxvXA==} + '@nestjs/core@10.3.10': + resolution: {integrity: sha512-ZbQ4jovQyzHtCGCrzK5NdtW1SYO2fHSsgSY1+/9WdruYCUra+JDkWEXgZ4M3Hv480Dl3OXehAmY1wCOojeMyMQ==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/microservices': ^10.0.0 '@nestjs/platform-express': ^10.0.0 '@nestjs/websockets': ^10.0.0 - reflect-metadata: ^0.1.12 + reflect-metadata: ^0.1.12 || ^0.2.0 rxjs: ^7.1.0 peerDependenciesMeta: '@nestjs/microservices': @@ -705,13 +712,13 @@ packages: peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 - '@nestjs/mapped-types@2.0.4': - resolution: {integrity: sha512-xl+gUSp0B+ln1VSNoUftlglk8dfpUes3DHGxKZ5knuBxS5g2H/8p9/DSBOYWUfO5f4u9s6ffBPZ71WO+tbe5SA==} + '@nestjs/mapped-types@2.0.5': + resolution: {integrity: sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 class-transformer: ^0.4.0 || ^0.5.0 class-validator: ^0.13.0 || ^0.14.0 - reflect-metadata: ^0.1.12 + reflect-metadata: ^0.1.12 || ^0.2.0 peerDependenciesMeta: class-transformer: optional: true @@ -724,26 +731,26 @@ packages: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 passport: ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 - '@nestjs/platform-express@10.3.1': - resolution: {integrity: sha512-Rj21quI5h4Lry7q9an+nO4ADQiQUy9A6XK74o5aTUHo3Ysm25ujqh2NgU4XbT3M2oXU9qzhE59OfhkQ7ZUvTAg==} + '@nestjs/platform-express@10.3.10': + resolution: {integrity: sha512-wK2ow3CZI2KFqWeEpPmoR300OB6BcBLxARV1EiClJLCj4S1mZsoCmS0YWgpk3j1j6mo0SI8vNLi/cC2iZPEPQA==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 - '@nestjs/schematics@10.1.0': - resolution: {integrity: sha512-HQWvD3F7O0Sv3qHS2jineWxPLmBTLlyjT6VdSw2EAIXulitmV+ErxB3TCVQQORlNkl5p5cwRYWyBaOblDbNFIQ==} + '@nestjs/schematics@10.1.2': + resolution: {integrity: sha512-S0bMtZM5U4mAiqkhRyZkXgjmOHBS5P/lp/vEydgMR4F7csOShc3jFeKVs1Eghd9xCFezGKy3SHy7hFT6dpPhWQ==} peerDependencies: typescript: '>=4.8.2' - '@nestjs/swagger@7.2.0': - resolution: {integrity: sha512-W7WPq561/79w27ZEgViXS7c5hqPwT7QXhsLsSeu2jeBROUhMM825QKDFKbMmtb643IW5dznJ4PjherlZZgtMvg==} + '@nestjs/swagger@7.4.0': + resolution: {integrity: sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==} peerDependencies: - '@fastify/static': ^6.0.0 + '@fastify/static': ^6.0.0 || ^7.0.0 '@nestjs/common': ^9.0.0 || ^10.0.0 '@nestjs/core': ^9.0.0 || ^10.0.0 class-transformer: '*' class-validator: '*' - reflect-metadata: ^0.1.12 + reflect-metadata: ^0.1.12 || ^0.2.0 peerDependenciesMeta: '@fastify/static': optional: true @@ -752,8 +759,8 @@ packages: class-validator: optional: true - '@nestjs/testing@10.3.1': - resolution: {integrity: sha512-74aSAugWT31jSPnStyRWDXgjHXWO3GYaUfAZ2T7Dml88UGkGy95iwaWgYy7aYM8/xVFKcDYkfL5FAYqZYce/yg==} + '@nestjs/testing@10.3.10': + resolution: {integrity: sha512-i3HAtVQJijxNxJq1k39aelyJlyEIBRONys7IipH/4r8W0J+M1V+y5EKDOyi4j1SdNSb/vmNyWpZ2/ewZjl3kRA==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 @@ -789,8 +796,8 @@ packages: '@polka/url@0.5.0': resolution: {integrity: sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==} - '@prisma/client@5.8.1': - resolution: {integrity: sha512-xQtMPfbIwLlbm0VVIVQY2yqQVOxPwRQhvIp7Z3m2900g1bu/zRHKhYZJQWELqmjl6d8YwBy0K2NvMqh47v1ubw==} + '@prisma/client@5.17.0': + resolution: {integrity: sha512-N2tnyKayT0Zf7mHjwEyE8iG7FwTmXDHFZ1GnNhQp0pJUObsuel4ZZ1XwfuAYkq5mRIiC/Kot0kt0tGCfLJ70Jw==} engines: {node: '>=16.13'} peerDependencies: prisma: '*' @@ -798,26 +805,26 @@ packages: prisma: optional: true - '@prisma/debug@5.8.1': - resolution: {integrity: sha512-tjuw7eA0Us3T42jx9AmAgL58rzwzpFGYc3R7Y4Ip75EBYrKMBA1YihuWMcBC92ILmjlQ/u3p8VxcIE0hr+fZfg==} + '@prisma/debug@5.17.0': + resolution: {integrity: sha512-l7+AteR3P8FXiYyo496zkuoiJ5r9jLQEdUuxIxNCN1ud8rdbH3GTxm+f+dCyaSv9l9WY+29L9czaVRXz9mULfg==} - '@prisma/engines-version@5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2': - resolution: {integrity: sha512-f5C3JM3l9yhGr3cr4FMqWloFaSCpNpMi58Om22rjD2DOz3owci2mFdFXMgnAGazFPKrCbbEhcxdsRfspEYRoFQ==} + '@prisma/engines-version@5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053': + resolution: {integrity: sha512-tUuxZZysZDcrk5oaNOdrBnnkoTtmNQPkzINFDjz7eG6vcs9AVDmA/F6K5Plsb2aQc/l5M2EnFqn3htng9FA4hg==} - '@prisma/engines@5.8.1': - resolution: {integrity: sha512-TJgYLRrZr56uhqcXO4GmP5be+zjCIHtLDK20Cnfg+o9d905hsN065QOL+3Z0zQAy6YD31Ol4u2kzSfRmbJv/uA==} + '@prisma/engines@5.17.0': + resolution: {integrity: sha512-+r+Nf+JP210Jur+/X8SIPLtz+uW9YA4QO5IXA+KcSOBe/shT47bCcRMTYCbOESw3FFYFTwe7vU6KTWHKPiwvtg==} - '@prisma/fetch-engine@5.8.1': - resolution: {integrity: sha512-+bgjjoSFa6uYEbAPlklfoVSStOEfcpheOjoBoNsNNSQdSzcwE2nM4Q0prun0+P8/0sCHo18JZ9xqa8gObvgOUw==} + '@prisma/fetch-engine@5.17.0': + resolution: {integrity: sha512-ESxiOaHuC488ilLPnrv/tM2KrPhQB5TRris/IeIV4ZvUuKeaicCl4Xj/JCQeG9IlxqOgf1cCg5h5vAzlewN91Q==} - '@prisma/get-platform@5.8.1': - resolution: {integrity: sha512-wnA+6HTFcY+tkykMokix9GiAkaauPC5W/gg0O5JB0J8tCTNWrqpnQ7AsaGRfkYUbeOIioh6woDjQrGTTRf1Zag==} + '@prisma/get-platform@5.17.0': + resolution: {integrity: sha512-UlDgbRozCP1rfJ5Tlkf3Cnftb6srGrEQ4Nm3og+1Se2gWmCZ0hmPIi+tQikGDUVLlvOWx3Gyi9LzgRP+HTXV9w==} '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@sinonjs/commons@3.0.0': - resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} @@ -828,8 +835,8 @@ packages: '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - '@tsconfig/node10@1.0.9': - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} @@ -846,14 +853,14 @@ packages: '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - '@types/babel__generator@7.6.7': - resolution: {integrity: sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==} + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.4': - resolution: {integrity: sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==} + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} '@types/bcryptjs@2.4.6': resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==} @@ -867,14 +874,14 @@ packages: '@types/eslint-scope@3.7.7': resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - '@types/eslint@8.44.9': - resolution: {integrity: sha512-6yBxcvwnnYoYT1Uk2d+jvIfsuP4mb2EdIxFnrPABj5a/838qe5bGkNLFOiipX4ULQ7XVQvTxOh7jO+BTAiqsEw==} + '@types/eslint@8.56.10': + resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/express-serve-static-core@4.17.41': - resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} + '@types/express-serve-static-core@4.19.5': + resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} @@ -903,12 +910,12 @@ packages: '@types/jsonwebtoken@9.0.5': resolution: {integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==} + '@types/jsonwebtoken@9.0.6': + resolution: {integrity: sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==} + '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/mime@3.0.4': - resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} - '@types/multer@1.4.11': resolution: {integrity: sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==} @@ -933,29 +940,26 @@ packages: '@types/pdfkit@0.13.4': resolution: {integrity: sha512-ixGNDHYJCCKuamY305wbfYSphZ2WPe8FPkjn8oF4fHV+PgPV4V+hecPh2VOS2h4RNtpSB3zQcR4sCpNvvrEb1A==} - '@types/qs@6.9.10': - resolution: {integrity: sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==} + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/semver@7.5.6': - resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} '@types/send@0.17.4': resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - '@types/serve-static@1.15.5': - resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/uuid@9.0.8': - resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - - '@types/validator@13.11.8': - resolution: {integrity: sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ==} + '@types/validator@13.12.0': + resolution: {integrity: sha512-nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -1024,8 +1028,8 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - '@webassemblyjs/ast@1.11.6': - resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} + '@webassemblyjs/ast@1.12.1': + resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} '@webassemblyjs/floating-point-hex-parser@1.11.6': resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} @@ -1033,8 +1037,8 @@ packages: '@webassemblyjs/helper-api-error@1.11.6': resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} - '@webassemblyjs/helper-buffer@1.11.6': - resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==} + '@webassemblyjs/helper-buffer@1.12.1': + resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} '@webassemblyjs/helper-numbers@1.11.6': resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} @@ -1042,8 +1046,8 @@ packages: '@webassemblyjs/helper-wasm-bytecode@1.11.6': resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} - '@webassemblyjs/helper-wasm-section@1.11.6': - resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==} + '@webassemblyjs/helper-wasm-section@1.12.1': + resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} '@webassemblyjs/ieee754@1.11.6': resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} @@ -1054,20 +1058,20 @@ packages: '@webassemblyjs/utf8@1.11.6': resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} - '@webassemblyjs/wasm-edit@1.11.6': - resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==} + '@webassemblyjs/wasm-edit@1.12.1': + resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} - '@webassemblyjs/wasm-gen@1.11.6': - resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==} + '@webassemblyjs/wasm-gen@1.12.1': + resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} - '@webassemblyjs/wasm-opt@1.11.6': - resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==} + '@webassemblyjs/wasm-opt@1.12.1': + resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} - '@webassemblyjs/wasm-parser@1.11.6': - resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==} + '@webassemblyjs/wasm-parser@1.12.1': + resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} - '@webassemblyjs/wast-printer@1.11.6': - resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==} + '@webassemblyjs/wast-printer@1.12.1': + resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -1082,8 +1086,8 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} - acorn-import-assertions@1.9.0: - resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: acorn: ^8 @@ -1092,12 +1096,12 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.1: - resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==} + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} - acorn@8.11.2: - resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1208,8 +1212,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.6.7: - resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -1256,17 +1260,13 @@ packages: bignumber.js@9.0.0: resolution: {integrity: sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==} - binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -1277,15 +1277,15 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} brotli@1.3.3: resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} - browserslist@4.22.2: - resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + browserslist@4.23.2: + resolution: {integrity: sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1313,9 +1313,6 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} - call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -1332,11 +1329,11 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001570: - resolution: {integrity: sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==} + caniuse-lite@1.0.30001642: + resolution: {integrity: sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==} - centra@2.6.0: - resolution: {integrity: sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ==} + centra@2.7.0: + resolution: {integrity: sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -1360,20 +1357,20 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - chrome-trace-event@1.0.3: - resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cjs-module-lexer@1.2.3: - resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + cjs-module-lexer@1.3.1: + resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} class-transformer@0.5.1: resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} @@ -1393,8 +1390,8 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} - cli-table3@0.6.3: - resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} cli-truncate@1.1.0: @@ -1490,8 +1487,8 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} core-util-is@1.0.2: @@ -1540,8 +1537,8 @@ packages: supports-color: optional: true - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1549,8 +1546,8 @@ packages: supports-color: optional: true - dedent@1.5.1: - resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -1574,10 +1571,6 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} - engines: {node: '>= 0.4'} - define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -1598,8 +1591,8 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-libc@2.0.2: - resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} detect-newline@3.1.0: @@ -1629,8 +1622,8 @@ packages: resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} engines: {node: '>=12'} - dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} eastasianwidth@0.2.0: @@ -1642,8 +1635,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.4.614: - resolution: {integrity: sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==} + electron-to-chromium@1.4.830: + resolution: {integrity: sha512-TrPKKH20HeN0J1LHzsYLs2qwXrp8TF4nHdu4sq61ozGbzMpWhI7iIOPYPPkxeq1azMT9PZ8enPFcftbs/Npcjg==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -1659,8 +1652,8 @@ packages: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} - enhanced-resolve@5.15.0: - resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} + enhanced-resolve@5.17.0: + resolution: {integrity: sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==} engines: {node: '>=10.13.0'} env-cmd@10.1.0: @@ -1682,11 +1675,11 @@ packages: es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-module-lexer@1.4.1: - resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} - escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} escape-html@1.0.3: @@ -1704,10 +1697,6 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - eslint-config-prettier@8.10.0: resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} hasBin: true @@ -1737,8 +1726,8 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true @@ -1751,8 +1740,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -1791,8 +1780,8 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} external-editor@2.2.0: @@ -1826,12 +1815,12 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-xml-parser@4.3.6: - resolution: {integrity: sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==} + fast-xml-parser@4.4.0: + resolution: {integrity: sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==} hasBin: true - fastq@1.16.0: - resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -1844,20 +1833,16 @@ packages: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} - figures@5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} - file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} - file-type@19.0.0: - resolution: {integrity: sha512-s7cxa7/leUWLiXO78DVVfBVse+milos9FitauDLG1pI7lNaJ2+5lzPnr2N24ym+84HVwJL6hVuGfgVE+ALvU8Q==} + file-type@19.2.0: + resolution: {integrity: sha512-tUgGaVcM7enfk+toLsBbbCP71iIThjBiMWLk1gYUprcY21/uRNnui0Py9oJ5AIXE7EJYfBeJRAl8pNHBmujboQ==} engines: {node: '>=18'} - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} finalhandler@1.2.0: @@ -1876,8 +1861,8 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} - flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} follow-redirects@1.15.6: resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} @@ -1894,8 +1879,8 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} fork-ts-checker-webpack-plugin@9.0.2: @@ -1924,8 +1909,8 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-monkey@1.0.5: - resolution: {integrity: sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==} + fs-monkey@1.0.6: + resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1953,9 +1938,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} - get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -1979,17 +1961,14 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} - engines: {node: '>=16 || 14 >=14.17'} + glob@10.4.2: + resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==} + engines: {node: '>=16 || 14 >=14.18'} hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - - glob@9.3.5: - resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} - engines: {node: '>=16 || 14 >=14.17'} + deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -2027,14 +2006,11 @@ packages: resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} engines: {node: '>=8'} - has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} - has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} has-symbols@1.0.3: @@ -2045,8 +2021,8 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} homedir@0.6.0: @@ -2073,8 +2049,8 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.0: - resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} import-fresh@3.3.0: @@ -2092,6 +2068,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -2114,18 +2091,14 @@ packages: resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} engines: {node: '>=12.0.0'} - inquirer@9.2.11: - resolution: {integrity: sha512-B2LafrnnhbRzCWfAdOXisUzL89Kg8cVJlYmhqoi3flSiV/TveO+nsXwgKr9h9PIo+J1hz7nBSk6gegRIMBBf7g==} - engines: {node: '>=14.18.0'} + inquirer@9.2.15: + resolution: {integrity: sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==} + engines: {node: '>=18'} internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} - interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} - ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -2159,8 +2132,9 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.15.0: + resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + engines: {node: '>= 0.4'} is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -2190,8 +2164,9 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} - is-map@2.0.2: - resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} @@ -2209,8 +2184,9 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} - is-set@2.0.2: - resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} is-shared-array-buffer@1.0.3: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} @@ -2232,15 +2208,13 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - - is-weakmap@2.0.1: - resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} - is-weakset@2.0.2: - resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -2259,8 +2233,8 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} - istanbul-lib-instrument@6.0.1: - resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} engines: {node: '>=10'} istanbul-lib-report@3.0.1: @@ -2271,17 +2245,16 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} - istanbul-reports@3.1.6: - resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} iterare@1.2.1: resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} engines: {node: '>=6'} - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} @@ -2458,8 +2431,11 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + jsonc-parser@3.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -2499,8 +2475,8 @@ packages: engines: {node: '>=10.13.0'} deprecated: This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md - ldapts@7.0.12: - resolution: {integrity: sha512-orwgIejUi/ZyGah9y8jWZmFUg8Ci5M8WAv0oZjSf3MVuk1sRBdor9Qy1ttGHbYpWj96HXKFunQ8AYZ8WWGp17g==} + ldapts@7.1.0: + resolution: {integrity: sha512-EGHJC1L9xFd9Qxevkq4hTi4I8KQ9Eh3F8Uzv7m1dviu5D8Ryq2Q4a52ddb49bDOv40UZuc37tuV94YPf+Ub/1g==} engines: {node: '>=18'} leven@3.1.0: @@ -2511,11 +2487,12 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - libphonenumber-js@1.10.54: - resolution: {integrity: sha512-P+38dUgJsmh0gzoRDoM4F5jLbyfztkU6PY6eSK6S5HwTi/LPvnwXqVCQZlAy1FxZ5c48q25QhxGQ0pq+WQcSlQ==} + libphonenumber-js@1.11.4: + resolution: {integrity: sha512-F/R50HQuWWYcmU/esP5jrH5LiWYaN7DpN0a/99U8+mnGGtnx8kmRE+649dQh3v+CowXXZc8vpkf5AmYkO0AQ7Q==} lightcookie@1.0.25: resolution: {integrity: sha512-SrY/+eBPaKAMnsn7mCsoOMZzoQyCyHHHZlFCu2fjo28XxSyCLjlooKiTxyrXTg8NPaHp1YzWi0lcGG1gDi6KHw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. linebreak@1.1.0: resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} @@ -2535,6 +2512,12 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + lodash.groupby@4.6.0: + resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==} + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} @@ -2550,6 +2533,9 @@ packages: lodash.isinteger@4.0.4: resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + lodash.isnil@4.0.0: + resolution: {integrity: sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==} + lodash.isnumber@3.0.3: resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} @@ -2559,6 +2545,9 @@ packages: lodash.isstring@4.0.1: resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.isundefined@3.0.1: + resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==} + lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} @@ -2571,6 +2560,9 @@ packages: lodash.partialright@4.2.1: resolution: {integrity: sha512-yebmPMQZH7i4El6SdJTW9rn8irWl8VTcsmiWqm/I4sY8/ZjbSo0Z512HL6soeAu3mh5rhx5uIIo6kYJOQXbCxw==} + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -2578,19 +2570,14 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - lru-cache@10.1.0: - resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} - engines: {node: 14 || >=16.14} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - magic-string@0.30.5: - resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} + magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} make-dir@4.0.0: @@ -2629,8 +2616,8 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} mime-db@1.52.0: @@ -2660,23 +2647,15 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - - minipass@7.0.4: - resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} mkdirp@0.5.6: @@ -2749,8 +2728,8 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + node-releases@2.0.17: + resolution: {integrity: sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -2767,11 +2746,12 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} - object-is@1.1.5: - resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} engines: {node: '>= 0.4'} object-keys@1.1.1: @@ -2800,8 +2780,8 @@ packages: openapi-fuzzer-core@1.0.6: resolution: {integrity: sha512-FJNJIfgUFuv4NmVGq9MYdoKra2GrkDy2uhIjE2YGlw30UA1glf4SXLMhI4UwdcJ8jisKdIxi7lXrfej8GvNW5w==} - optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} ora@5.4.1: @@ -2832,11 +2812,14 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - pactum-matchers@1.1.6: - resolution: {integrity: sha512-55io32NeOKbLpHKKPzYDOr+N2dseTzMbj1Gj1y+zvOkKK6NDf5BT5pxglfqLN/ra3ig5zvbrKFUqZIWjAWboog==} + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + pactum-matchers@1.1.7: + resolution: {integrity: sha512-RqwewcUje6vhcYQGbPfdSXkcp/Vtwn4WmmTWLSmqp0CGxBroCEqRg3JMIjkjQTZCd2VmG+tTcQw+n4P/iuqv3Q==} - pactum@3.6.0: - resolution: {integrity: sha512-pR3OzFXi7K3oNADMoEiC8Err51aCJS3FTS0MXHqqr3YDlSCb/NcdJjcoTGh443W0WilvnHFL4OsaGtO0sWv76A==} + pactum@3.7.0: + resolution: {integrity: sha512-zYw+84hb/rQZ2/mEw2xla/qowLnOvlIvbTYeAhQS2pu3ZAyx+pXJLntcCqZ0QI9PUWwx8HqCzm2qBclZTtZUzw==} engines: {node: '>=10'} pad@2.3.0: @@ -2868,8 +2851,8 @@ packages: resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} engines: {node: '>= 0.4.0'} - passport@0.6.0: - resolution: {integrity: sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==} + passport@0.7.0: + resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==} engines: {node: '>= 0.4.0'} path-exists@4.0.0: @@ -2887,9 +2870,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.10.1: - resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} - engines: {node: '>=16 || 14 >=14.17'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} @@ -2907,24 +2890,24 @@ packages: pdfkit@0.14.0: resolution: {integrity: sha512-Hnor8/78jhHm6ONrxWhrqOwAVALlBnFyWOF8sstBZMiqHZgZ5A6RU+Q3yahhw82plxpT7LOfH3b3qcOX6rzMQg==} - peek-readable@5.0.0: - resolution: {integrity: sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==} + peek-readable@5.1.3: + resolution: {integrity: sha512-kCsc9HwH5RgVA3H3VqkWFyGQwsxUxLdiSX1d5nqAm7hnMFjNFX1VhBLmJoUY0hZNc8gmDNgBkLjfhiWPsziXWA==} engines: {node: '>=14.16'} - phin@3.7.0: - resolution: {integrity: sha512-DqnVNrpYhKGBZppNKprD+UJylMeEKOZxHgPB+ZP6mGzf3uA2uox4Ep9tUm+rUc8WLIdHT3HcAE4X8fhwQA9JKg==} + phin@3.7.1: + resolution: {integrity: sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==} engines: {node: '>= 8'} - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@3.0.1: - resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} - engines: {node: '>=10'} + picomatch@4.0.1: + resolution: {integrity: sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==} + engines: {node: '>=12'} pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} @@ -2974,8 +2957,8 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - prisma@5.8.1: - resolution: {integrity: sha512-N6CpjzECnUHZ5beeYpDzkt2rYpEdAeqXX2dweu6BoQaeYkNZrC/WJHM+5MO/uidFHTak8QhkPKBWck1o/4MD4A==} + prisma@5.17.0: + resolution: {integrity: sha512-m4UWkN5lBE6yevqeOxEvmepnL5cNPEjzMw2IqDB59AcEV6w7D8vGljDLd1gPFH+W6gUxw9x7/RmN5dCS/WTPxA==} engines: {node: '>=16.13'} hasBin: true @@ -3001,8 +2984,8 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - pure-rand@6.0.4: - resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==} + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} @@ -3018,16 +3001,12 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} @@ -3047,18 +3026,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readable-web-to-node-stream@3.0.2: - resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} - engines: {node: '>=8'} - readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - reflect-metadata@0.1.14: resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==} @@ -3115,11 +3086,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - - rimraf@4.4.1: - resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} - engines: {node: '>=14'} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true run-async@2.4.1: @@ -3167,8 +3134,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true @@ -3176,19 +3143,15 @@ packages: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} - serialize-javascript@6.0.1: - resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} serve-static@1.15.0: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} - set-function-length@1.1.1: - resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} - engines: {node: '>= 0.4'} - - set-function-length@1.2.1: - resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} set-function-name@2.0.2: @@ -3198,9 +3161,9 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sharp@0.33.2: - resolution: {integrity: sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==} - engines: {libvips: '>=8.15.1', node: ^18.17.0 || ^20.3.0 || >=21.0.0} + sharp@0.33.4: + resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==} + engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -3210,13 +3173,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true - - side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -3256,14 +3215,14 @@ packages: spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.16: - resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + spdx-license-ids@3.0.18: + resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -3344,9 +3303,9 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - strtok3@7.0.0: - resolution: {integrity: sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==} - engines: {node: '>=14.16'} + strtok3@8.0.0: + resolution: {integrity: sha512-YzsSP+kli3q1tTA04HsfY1GqIapi3vEMN38jJ+aLpFyoev0onI/RuZWBGkQgc7ORynb3LW4cSOP3XtsKV21X6Q==} + engines: {node: '>=16'} supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -3364,8 +3323,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - swagger-ui-dist@5.11.0: - resolution: {integrity: sha512-j0PIATqQSEFGOLmiJOJZj1X1Jt6bFIur3JpY7+ghliUnfZs0fpWDdHEkn9q7QUlBtKbkn6TepvSxTqnE8l3s0A==} + swagger-ui-dist@5.17.14: + resolution: {integrity: sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==} symbol-observable@1.0.1: resolution: {integrity: sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==} @@ -3379,8 +3338,8 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - terser-webpack-plugin@5.3.9: - resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} + terser-webpack-plugin@5.3.10: + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -3395,8 +3354,8 @@ packages: uglify-js: optional: true - terser@5.26.0: - resolution: {integrity: sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==} + terser@5.31.3: + resolution: {integrity: sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==} engines: {node: '>=10'} hasBin: true @@ -3432,8 +3391,8 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - token-types@5.0.1: - resolution: {integrity: sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==} + token-types@6.0.0: + resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} engines: {node: '>=14.16'} tr46@0.0.3: @@ -3500,8 +3459,8 @@ packages: tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} tsutils@3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} @@ -3554,6 +3513,10 @@ packages: resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} engines: {node: '>=8'} + uint8array-extras@1.4.0: + resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + engines: {node: '>=18'} + unicode-properties@1.4.1: resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} @@ -3568,8 +3531,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.0.13: - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -3584,26 +3547,22 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} - uuid@9.0.0: - resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} - hasBin: true - - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - validator@13.11.0: - resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} engines: {node: '>= 0.10'} vary@1.1.2: @@ -3625,8 +3584,8 @@ packages: walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - watchpack@2.4.0: - resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} + watchpack@2.4.1: + resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} engines: {node: '>=10.13.0'} wcwidth@1.0.1: @@ -3643,8 +3602,8 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - webpack@5.89.0: - resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} + webpack@5.92.1: + resolution: {integrity: sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -3659,11 +3618,12 @@ packages: which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - which-collection@1.0.1: - resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} - which-typed-array@1.1.14: - resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} which@2.0.2: @@ -3671,6 +3631,10 @@ packages: engines: {node: '>= 8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -3701,9 +3665,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -3722,40 +3683,38 @@ packages: snapshots: - '@aashutoshrathi/word-wrap@1.2.6': {} - - '@ampproject/remapping@2.2.1': + '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 - '@angular-devkit/core@17.0.9(chokidar@3.5.3)': + '@angular-devkit/core@17.3.8(chokidar@3.6.0)': dependencies: ajv: 8.12.0 ajv-formats: 2.1.1(ajv@8.12.0) - jsonc-parser: 3.2.0 - picomatch: 3.0.1 + jsonc-parser: 3.2.1 + picomatch: 4.0.1 rxjs: 7.8.1 source-map: 0.7.4 optionalDependencies: - chokidar: 3.5.3 + chokidar: 3.6.0 - '@angular-devkit/schematics-cli@17.0.9(chokidar@3.5.3)': + '@angular-devkit/schematics-cli@17.3.8(chokidar@3.6.0)': dependencies: - '@angular-devkit/core': 17.0.9(chokidar@3.5.3) - '@angular-devkit/schematics': 17.0.9(chokidar@3.5.3) + '@angular-devkit/core': 17.3.8(chokidar@3.6.0) + '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) ansi-colors: 4.1.3 - inquirer: 9.2.11 + inquirer: 9.2.15 symbol-observable: 4.0.0 yargs-parser: 21.1.1 transitivePeerDependencies: - chokidar - '@angular-devkit/schematics@17.0.9(chokidar@3.5.3)': + '@angular-devkit/schematics@17.3.8(chokidar@3.6.0)': dependencies: - '@angular-devkit/core': 17.0.9(chokidar@3.5.3) - jsonc-parser: 3.2.0 - magic-string: 0.30.5 + '@angular-devkit/core': 17.3.8(chokidar@3.6.0) + jsonc-parser: 3.2.1 + magic-string: 0.30.8 ora: 5.4.1 rxjs: 7.8.1 transitivePeerDependencies: @@ -3763,201 +3722,209 @@ snapshots: '@arr/every@1.0.1': {} - '@babel/code-frame@7.23.5': + '@babel/code-frame@7.24.7': dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 - '@babel/compat-data@7.23.5': {} + '@babel/compat-data@7.24.9': {} - '@babel/core@7.23.6': + '@babel/core@7.24.9': dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.6) - '@babel/helpers': 7.23.6 - '@babel/parser': 7.23.6 - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.6 - '@babel/types': 7.23.6 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.10 + '@babel/helper-compilation-targets': 7.24.8 + '@babel/helper-module-transforms': 7.24.9(@babel/core@7.24.9) + '@babel/helpers': 7.24.8 + '@babel/parser': 7.24.8 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.9 convert-source-map: 2.0.0 - debug: 4.3.4 + debug: 4.3.5 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.23.6': + '@babel/generator@7.24.10': dependencies: - '@babel/types': 7.23.6 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 + '@babel/types': 7.24.9 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.24.8': dependencies: - '@babel/compat-data': 7.23.5 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.22.2 + '@babel/compat-data': 7.24.9 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.23.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-environment-visitor@7.22.20': {} + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.24.9 - '@babel/helper-function-name@7.23.0': + '@babel/helper-function-name@7.24.7': dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 + '@babel/template': 7.24.7 + '@babel/types': 7.24.9 - '@babel/helper-hoist-variables@7.22.5': + '@babel/helper-hoist-variables@7.24.7': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.24.9 - '@babel/helper-module-imports@7.22.15': + '@babel/helper-module-imports@7.24.7': dependencies: - '@babel/types': 7.23.6 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.9 + transitivePeerDependencies: + - supports-color - '@babel/helper-module-transforms@7.23.3(@babel/core@7.23.6)': + '@babel/helper-module-transforms@7.24.9(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 + '@babel/core': 7.24.9 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-plugin-utils@7.22.5': {} + '@babel/helper-plugin-utils@7.24.8': {} - '@babel/helper-simple-access@7.22.5': + '@babel/helper-simple-access@7.24.7': dependencies: - '@babel/types': 7.23.6 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.9 + transitivePeerDependencies: + - supports-color - '@babel/helper-split-export-declaration@7.22.6': + '@babel/helper-split-export-declaration@7.24.7': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.24.9 - '@babel/helper-string-parser@7.23.4': {} + '@babel/helper-string-parser@7.24.8': {} - '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.24.7': {} - '@babel/helper-validator-option@7.23.5': {} + '@babel/helper-validator-option@7.24.8': {} - '@babel/helpers@7.23.6': + '@babel/helpers@7.24.8': dependencies: - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.6 - '@babel/types': 7.23.6 - transitivePeerDependencies: - - supports-color + '@babel/template': 7.24.7 + '@babel/types': 7.24.9 - '@babel/highlight@7.23.4': + '@babel/highlight@7.24.7': dependencies: - '@babel/helper-validator-identifier': 7.22.20 + '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 + picocolors: 1.0.1 - '@babel/parser@7.23.6': + '@babel/parser@7.24.8': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.24.9 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.6)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.6)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.6)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.6)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.6)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.6)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.24.8 - '@babel/template@7.22.15': + '@babel/template@7.24.7': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.9 - '@babel/traverse@7.23.6': + '@babel/traverse@7.24.8': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - debug: 4.3.4 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.10 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.9 + debug: 4.3.5 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.23.6': + '@babel/types@7.24.9': dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 '@bcoe/v8-coverage@0.2.3': {} @@ -3969,25 +3936,25 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@emnapi/runtime@0.45.0': + '@emnapi/runtime@1.2.0': dependencies: - tslib: 2.6.2 + tslib: 2.6.3 optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.56.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': dependencies: - eslint: 8.56.0 + eslint: 8.57.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.10.0': {} + '@eslint-community/regexpp@4.11.0': {} '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.4 + debug: 4.3.5 espree: 9.6.1 globals: 13.24.0 - ignore: 5.3.0 + ignore: 5.3.1 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -3995,97 +3962,106 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.56.0': {} + '@eslint/js@8.57.0': {} '@exodus/schemasafe@1.3.0': {} '@faker-js/faker@7.6.0': {} - '@humanwhocodes/config-array@0.11.13': + '@fast-csv/parse@5.0.0': + dependencies: + lodash.escaperegexp: 4.1.2 + lodash.groupby: 4.6.0 + lodash.isfunction: 3.0.9 + lodash.isnil: 4.0.0 + lodash.isundefined: 3.0.1 + lodash.uniq: 4.5.0 + + '@humanwhocodes/config-array@0.11.14': dependencies: - '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4 + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.5 minimatch: 3.1.2 transitivePeerDependencies: - supports-color '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.1': {} + '@humanwhocodes/object-schema@2.0.3': {} - '@img/sharp-darwin-arm64@0.33.2': + '@img/sharp-darwin-arm64@0.33.4': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.1 + '@img/sharp-libvips-darwin-arm64': 1.0.2 optional: true - '@img/sharp-darwin-x64@0.33.2': + '@img/sharp-darwin-x64@0.33.4': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.1 + '@img/sharp-libvips-darwin-x64': 1.0.2 optional: true - '@img/sharp-libvips-darwin-arm64@1.0.1': + '@img/sharp-libvips-darwin-arm64@1.0.2': optional: true - '@img/sharp-libvips-darwin-x64@1.0.1': + '@img/sharp-libvips-darwin-x64@1.0.2': optional: true - '@img/sharp-libvips-linux-arm64@1.0.1': + '@img/sharp-libvips-linux-arm64@1.0.2': optional: true - '@img/sharp-libvips-linux-arm@1.0.1': + '@img/sharp-libvips-linux-arm@1.0.2': optional: true - '@img/sharp-libvips-linux-s390x@1.0.1': + '@img/sharp-libvips-linux-s390x@1.0.2': optional: true - '@img/sharp-libvips-linux-x64@1.0.1': + '@img/sharp-libvips-linux-x64@1.0.2': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.0.1': + '@img/sharp-libvips-linuxmusl-arm64@1.0.2': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.0.1': + '@img/sharp-libvips-linuxmusl-x64@1.0.2': optional: true - '@img/sharp-linux-arm64@0.33.2': + '@img/sharp-linux-arm64@0.33.4': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.1 + '@img/sharp-libvips-linux-arm64': 1.0.2 optional: true - '@img/sharp-linux-arm@0.33.2': + '@img/sharp-linux-arm@0.33.4': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.1 + '@img/sharp-libvips-linux-arm': 1.0.2 optional: true - '@img/sharp-linux-s390x@0.33.2': + '@img/sharp-linux-s390x@0.33.4': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.1 + '@img/sharp-libvips-linux-s390x': 1.0.2 optional: true - '@img/sharp-linux-x64@0.33.2': + '@img/sharp-linux-x64@0.33.4': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.1 + '@img/sharp-libvips-linux-x64': 1.0.2 optional: true - '@img/sharp-linuxmusl-arm64@0.33.2': + '@img/sharp-linuxmusl-arm64@0.33.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 optional: true - '@img/sharp-linuxmusl-x64@0.33.2': + '@img/sharp-linuxmusl-x64@0.33.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.1 + '@img/sharp-libvips-linuxmusl-x64': 1.0.2 optional: true - '@img/sharp-wasm32@0.33.2': + '@img/sharp-wasm32@0.33.4': dependencies: - '@emnapi/runtime': 0.45.0 + '@emnapi/runtime': 1.2.0 optional: true - '@img/sharp-win32-ia32@0.33.2': + '@img/sharp-win32-ia32@0.33.4': optional: true - '@img/sharp-win32-x64@0.33.2': + '@img/sharp-win32-x64@0.33.4': optional: true '@isaacs/cliui@8.0.2': @@ -4142,7 +4118,7 @@ snapshots: jest-util: 29.7.0 jest-validate: 29.7.0 jest-watcher: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 pretty-format: 29.7.0 slash: 3.0.0 strip-ansi: 6.0.1 @@ -4194,7 +4170,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/trace-mapping': 0.3.25 '@types/node': 18.15.11 chalk: 4.1.2 collect-v8-coverage: 1.0.2 @@ -4202,17 +4178,17 @@ snapshots: glob: 7.2.3 graceful-fs: 4.2.11 istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.1 + istanbul-lib-instrument: 6.0.3 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.6 + istanbul-reports: 3.1.7 jest-message-util: 29.7.0 jest-util: 29.7.0 jest-worker: 29.7.0 slash: 3.0.0 string-length: 4.0.2 strip-ansi: 6.0.1 - v8-to-istanbul: 9.2.0 + v8-to-istanbul: 9.3.0 transitivePeerDependencies: - supports-color @@ -4222,7 +4198,7 @@ snapshots: '@jest/source-map@29.6.3': dependencies: - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 @@ -4242,9 +4218,9 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.23.6 + '@babel/core': 7.24.9 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -4253,7 +4229,7 @@ snapshots: jest-haste-map: 29.7.0 jest-regex-util: 29.6.3 jest-util: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 pirates: 4.0.6 slash: 3.0.0 write-file-atomic: 4.0.2 @@ -4269,184 +4245,183 @@ snapshots: '@types/yargs': 17.0.32 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.3': + '@jridgewell/gen-mapping@0.3.5': dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/resolve-uri@3.1.1': {} + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.1.2': {} + '@jridgewell/set-array@1.2.1': {} - '@jridgewell/source-map@0.3.5': + '@jridgewell/source-map@0.3.6': dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/trace-mapping@0.3.20': + '@jridgewell/trace-mapping@0.3.25': dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping@0.3.9': dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - '@ljharb/through@2.3.11': + '@ljharb/through@2.3.13': dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 '@lukeed/csprng@1.1.0': {} - '@nestjs/axios@3.0.2(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(axios@1.6.7)(rxjs@7.8.1)': + '@microsoft/tsdoc@0.15.0': {} + + '@nestjs/axios@3.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(axios@1.7.2)(rxjs@7.8.1)': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - axios: 1.6.7 + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + axios: 1.7.2 rxjs: 7.8.1 - '@nestjs/cli@10.3.0': + '@nestjs/cli@10.4.2': dependencies: - '@angular-devkit/core': 17.0.9(chokidar@3.5.3) - '@angular-devkit/schematics': 17.0.9(chokidar@3.5.3) - '@angular-devkit/schematics-cli': 17.0.9(chokidar@3.5.3) - '@nestjs/schematics': 10.1.0(chokidar@3.5.3)(typescript@5.3.3) + '@angular-devkit/core': 17.3.8(chokidar@3.6.0) + '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) + '@angular-devkit/schematics-cli': 17.3.8(chokidar@3.6.0) + '@nestjs/schematics': 10.1.2(chokidar@3.6.0)(typescript@5.3.3) chalk: 4.1.2 - chokidar: 3.5.3 - cli-table3: 0.6.3 + chokidar: 3.6.0 + cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.89.0) - glob: 10.3.10 + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.92.1) + glob: 10.4.2 inquirer: 8.2.6 node-emoji: 1.11.0 ora: 5.4.1 - rimraf: 4.4.1 - shelljs: 0.8.5 - source-map-support: 0.5.21 tree-kill: 1.2.2 tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.1.0 typescript: 5.3.3 - webpack: 5.89.0 + webpack: 5.92.1 webpack-node-externals: 3.0.0 transitivePeerDependencies: - esbuild - uglify-js - webpack-cli - '@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)': + '@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)': dependencies: iterare: 1.2.1 reflect-metadata: 0.1.14 rxjs: 7.8.1 - tslib: 2.6.2 + tslib: 2.6.3 uid: 2.0.2 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.14.1 - '@nestjs/config@3.1.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)': + '@nestjs/config@3.2.3(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(rxjs@7.8.1)': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - dotenv: 16.3.1 + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + dotenv: 16.4.5 dotenv-expand: 10.0.0 lodash: 4.17.21 - reflect-metadata: 0.1.14 - uuid: 9.0.0 + rxjs: 7.8.1 - '@nestjs/core@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)': + '@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1)': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 path-to-regexp: 3.2.0 reflect-metadata: 0.1.14 rxjs: 7.8.1 - tslib: 2.6.2 + tslib: 2.6.3 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1) + '@nestjs/platform-express': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10) transitivePeerDependencies: - encoding - '@nestjs/jwt@10.2.0(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))': + '@nestjs/jwt@10.2.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@types/jsonwebtoken': 9.0.5 jsonwebtoken: 9.0.2 - '@nestjs/mapped-types@2.0.4(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)': + '@nestjs/mapped-types@2.0.5(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) reflect-metadata: 0.1.14 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.14.1 - '@nestjs/passport@10.0.3(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(passport@0.6.0)': + '@nestjs/passport@10.0.3(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(passport@0.7.0)': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - passport: 0.6.0 + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + passport: 0.7.0 - '@nestjs/platform-express@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1)': + '@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10)': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) body-parser: 1.20.2 cors: 2.8.5 - express: 4.18.2 + express: 4.19.2 multer: 1.4.4-lts.1 - tslib: 2.6.2 + tslib: 2.6.3 transitivePeerDependencies: - supports-color - '@nestjs/schematics@10.1.0(chokidar@3.5.3)(typescript@4.9.5)': + '@nestjs/schematics@10.1.2(chokidar@3.6.0)(typescript@4.9.5)': dependencies: - '@angular-devkit/core': 17.0.9(chokidar@3.5.3) - '@angular-devkit/schematics': 17.0.9(chokidar@3.5.3) + '@angular-devkit/core': 17.3.8(chokidar@3.6.0) + '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) comment-json: 4.2.3 - jsonc-parser: 3.2.0 + jsonc-parser: 3.3.1 pluralize: 8.0.0 typescript: 4.9.5 transitivePeerDependencies: - chokidar - '@nestjs/schematics@10.1.0(chokidar@3.5.3)(typescript@5.3.3)': + '@nestjs/schematics@10.1.2(chokidar@3.6.0)(typescript@5.3.3)': dependencies: - '@angular-devkit/core': 17.0.9(chokidar@3.5.3) - '@angular-devkit/schematics': 17.0.9(chokidar@3.5.3) + '@angular-devkit/core': 17.3.8(chokidar@3.6.0) + '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) comment-json: 4.2.3 - jsonc-parser: 3.2.0 + jsonc-parser: 3.3.1 pluralize: 8.0.0 typescript: 5.3.3 transitivePeerDependencies: - chokidar - '@nestjs/swagger@7.2.0(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)': + '@nestjs/swagger@7.4.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/mapped-types': 2.0.4(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14) + '@microsoft/tsdoc': 0.15.0 + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/mapped-types': 2.0.5(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14) js-yaml: 4.1.0 lodash: 4.17.21 path-to-regexp: 3.2.0 reflect-metadata: 0.1.14 - swagger-ui-dist: 5.11.0 + swagger-ui-dist: 5.17.14 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.14.1 - '@nestjs/testing@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1))': + '@nestjs/testing@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10))': dependencies: - '@nestjs/common': 10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - tslib: 2.6.2 + '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) + tslib: 2.6.3 optionalDependencies: - '@nestjs/platform-express': 10.3.1(@nestjs/common@10.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.1) + '@nestjs/platform-express': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.3.10) '@nodelib/fs.scandir@2.1.5': dependencies: @@ -4458,7 +4433,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.16.0 + fastq: 1.17.1 '@nuxtjs/opencollective@0.3.2': dependencies: @@ -4473,48 +4448,48 @@ snapshots: '@polka/url@0.5.0': {} - '@prisma/client@5.8.1(prisma@5.8.1)': + '@prisma/client@5.17.0(prisma@5.17.0)': optionalDependencies: - prisma: 5.8.1 + prisma: 5.17.0 - '@prisma/debug@5.8.1': {} + '@prisma/debug@5.17.0': {} - '@prisma/engines-version@5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2': {} + '@prisma/engines-version@5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053': {} - '@prisma/engines@5.8.1': + '@prisma/engines@5.17.0': dependencies: - '@prisma/debug': 5.8.1 - '@prisma/engines-version': 5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2 - '@prisma/fetch-engine': 5.8.1 - '@prisma/get-platform': 5.8.1 + '@prisma/debug': 5.17.0 + '@prisma/engines-version': 5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053 + '@prisma/fetch-engine': 5.17.0 + '@prisma/get-platform': 5.17.0 - '@prisma/fetch-engine@5.8.1': + '@prisma/fetch-engine@5.17.0': dependencies: - '@prisma/debug': 5.8.1 - '@prisma/engines-version': 5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2 - '@prisma/get-platform': 5.8.1 + '@prisma/debug': 5.17.0 + '@prisma/engines-version': 5.17.0-31.393aa359c9ad4a4bb28630fb5613f9c281cde053 + '@prisma/get-platform': 5.17.0 - '@prisma/get-platform@5.8.1': + '@prisma/get-platform@5.17.0': dependencies: - '@prisma/debug': 5.8.1 + '@prisma/debug': 5.17.0 '@sinclair/typebox@0.27.8': {} - '@sinonjs/commons@3.0.0': + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 '@sinonjs/fake-timers@10.3.0': dependencies: - '@sinonjs/commons': 3.0.0 + '@sinonjs/commons': 3.0.1 '@swc/helpers@0.3.17': dependencies: - tslib: 2.6.2 + tslib: 2.6.3 '@tokenizer/token@0.3.0': {} - '@tsconfig/node10@1.0.9': {} + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -4528,24 +4503,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - '@types/babel__generator': 7.6.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.9 + '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.4 + '@types/babel__traverse': 7.20.6 - '@types/babel__generator@7.6.7': + '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.24.9 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.9 - '@types/babel__traverse@7.20.4': + '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.24.9 '@types/bcryptjs@2.4.6': {} @@ -4560,29 +4535,29 @@ snapshots: '@types/eslint-scope@3.7.7': dependencies: - '@types/eslint': 8.44.9 + '@types/eslint': 8.56.10 '@types/estree': 1.0.5 - '@types/eslint@8.44.9': + '@types/eslint@8.56.10': dependencies: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 '@types/estree@1.0.5': {} - '@types/express-serve-static-core@4.17.41': + '@types/express-serve-static-core@4.19.5': dependencies: '@types/node': 18.15.11 - '@types/qs': 6.9.10 + '@types/qs': 6.9.15 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express@4.17.21': dependencies: '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.17.41 - '@types/qs': 6.9.10 - '@types/serve-static': 1.15.5 + '@types/express-serve-static-core': 4.19.5 + '@types/qs': 6.9.15 + '@types/serve-static': 1.15.7 '@types/graceful-fs@4.1.9': dependencies: @@ -4611,9 +4586,11 @@ snapshots: dependencies: '@types/node': 18.15.11 - '@types/mime@1.3.5': {} + '@types/jsonwebtoken@9.0.6': + dependencies: + '@types/node': 18.15.11 - '@types/mime@3.0.4': {} + '@types/mime@1.3.5': {} '@types/multer@1.4.11': dependencies: @@ -4630,7 +4607,7 @@ snapshots: '@types/passport-jwt@3.0.13': dependencies: '@types/express': 4.17.21 - '@types/jsonwebtoken': 9.0.5 + '@types/jsonwebtoken': 9.0.6 '@types/passport-strategy': 0.2.38 '@types/passport-strategy@0.2.38': @@ -4646,28 +4623,26 @@ snapshots: dependencies: '@types/node': 18.15.11 - '@types/qs@6.9.10': {} + '@types/qs@6.9.15': {} '@types/range-parser@1.2.7': {} - '@types/semver@7.5.6': {} + '@types/semver@7.5.8': {} '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 '@types/node': 18.15.11 - '@types/serve-static@1.15.5': + '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/mime': 3.0.4 '@types/node': 18.15.11 + '@types/send': 0.17.4 '@types/stack-utils@2.0.3': {} - '@types/uuid@9.0.8': {} - - '@types/validator@13.11.8': {} + '@types/validator@13.12.0': {} '@types/yargs-parser@21.0.3': {} @@ -4675,32 +4650,32 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@4.9.5))(eslint@8.56.0)(typescript@4.9.5)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@4.9.5))(eslint@8.57.0)(typescript@4.9.5)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@4.9.5) + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@4.9.5) '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.56.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + debug: 4.3.5 + eslint: 8.57.0 graphemer: 1.4.0 - ignore: 5.3.0 + ignore: 5.3.1 natural-compare-lite: 1.4.0 - semver: 7.5.4 + semver: 7.6.3 tsutils: 3.21.0(typescript@4.9.5) optionalDependencies: typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@4.9.5)': + '@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@4.9.5)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.56.0 + debug: 4.3.5 + eslint: 8.57.0 optionalDependencies: typescript: 4.9.5 transitivePeerDependencies: @@ -4711,12 +4686,12 @@ snapshots: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - '@typescript-eslint/type-utils@5.62.0(eslint@8.56.0)(typescript@4.9.5)': + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.0)(typescript@4.9.5)': dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - debug: 4.3.4 - eslint: 8.56.0 + '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@4.9.5) + debug: 4.3.5 + eslint: 8.57.0 tsutils: 3.21.0(typescript@4.9.5) optionalDependencies: typescript: 4.9.5 @@ -4729,27 +4704,27 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.4 + debug: 4.3.5 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.4 + semver: 7.6.3 tsutils: 3.21.0(typescript@4.9.5) optionalDependencies: typescript: 4.9.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@4.9.5)': + '@typescript-eslint/utils@5.62.0(eslint@8.57.0)(typescript@4.9.5)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 - '@types/semver': 7.5.6 + '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - eslint: 8.56.0 + eslint: 8.57.0 eslint-scope: 5.1.1 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color - typescript @@ -4761,7 +4736,7 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@webassemblyjs/ast@1.11.6': + '@webassemblyjs/ast@1.12.1': dependencies: '@webassemblyjs/helper-numbers': 1.11.6 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 @@ -4770,7 +4745,7 @@ snapshots: '@webassemblyjs/helper-api-error@1.11.6': {} - '@webassemblyjs/helper-buffer@1.11.6': {} + '@webassemblyjs/helper-buffer@1.12.1': {} '@webassemblyjs/helper-numbers@1.11.6': dependencies: @@ -4780,12 +4755,12 @@ snapshots: '@webassemblyjs/helper-wasm-bytecode@1.11.6': {} - '@webassemblyjs/helper-wasm-section@1.11.6': + '@webassemblyjs/helper-wasm-section@1.12.1': dependencies: - '@webassemblyjs/ast': 1.11.6 - '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/wasm-gen': 1.11.6 + '@webassemblyjs/wasm-gen': 1.12.1 '@webassemblyjs/ieee754@1.11.6': dependencies: @@ -4797,44 +4772,44 @@ snapshots: '@webassemblyjs/utf8@1.11.6': {} - '@webassemblyjs/wasm-edit@1.11.6': + '@webassemblyjs/wasm-edit@1.12.1': dependencies: - '@webassemblyjs/ast': 1.11.6 - '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/helper-wasm-section': 1.11.6 - '@webassemblyjs/wasm-gen': 1.11.6 - '@webassemblyjs/wasm-opt': 1.11.6 - '@webassemblyjs/wasm-parser': 1.11.6 - '@webassemblyjs/wast-printer': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-opt': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/wast-printer': 1.12.1 - '@webassemblyjs/wasm-gen@1.11.6': + '@webassemblyjs/wasm-gen@1.12.1': dependencies: - '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/ast': 1.12.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 '@webassemblyjs/ieee754': 1.11.6 '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 - '@webassemblyjs/wasm-opt@1.11.6': + '@webassemblyjs/wasm-opt@1.12.1': dependencies: - '@webassemblyjs/ast': 1.11.6 - '@webassemblyjs/helper-buffer': 1.11.6 - '@webassemblyjs/wasm-gen': 1.11.6 - '@webassemblyjs/wasm-parser': 1.11.6 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 - '@webassemblyjs/wasm-parser@1.11.6': + '@webassemblyjs/wasm-parser@1.12.1': dependencies: - '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/ast': 1.12.1 '@webassemblyjs/helper-api-error': 1.11.6 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 '@webassemblyjs/ieee754': 1.11.6 '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 - '@webassemblyjs/wast-printer@1.11.6': + '@webassemblyjs/wast-printer@1.12.1': dependencies: - '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 '@xtuc/ieee754@1.2.0': {} @@ -4848,17 +4823,19 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-assertions@1.9.0(acorn@8.11.2): + acorn-import-attributes@1.9.5(acorn@8.12.1): dependencies: - acorn: 8.11.2 + acorn: 8.12.1 - acorn-jsx@5.3.2(acorn@8.11.2): + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: - acorn: 8.11.2 + acorn: 8.12.1 - acorn-walk@8.3.1: {} + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 - acorn@8.11.2: {} + acorn@8.12.1: {} ajv-formats@2.1.1(ajv@8.12.0): optionalDependencies: @@ -4927,7 +4904,7 @@ snapshots: array-buffer-byte-length@1.0.1: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-array-buffer: 3.0.4 array-flatten@1.1.1: {} @@ -4948,7 +4925,7 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - axios@1.6.7: + axios@1.7.2: dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 @@ -4956,13 +4933,13 @@ snapshots: transitivePeerDependencies: - debug - babel-jest@29.7.0(@babel/core@7.23.6): + babel-jest@29.7.0(@babel/core@7.24.9): dependencies: - '@babel/core': 7.23.6 + '@babel/core': 7.24.9 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.23.6) + babel-preset-jest: 29.6.3(@babel/core@7.24.9) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -4971,7 +4948,7 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.8 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -4981,32 +4958,32 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 + '@babel/template': 7.24.7 + '@babel/types': 7.24.9 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.4 - - babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.6): - dependencies: - '@babel/core': 7.23.6 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.6) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.6) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.6) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.6) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.6) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.6) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.6) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.6) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.6) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.6) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.6) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.6) - - babel-preset-jest@29.6.3(@babel/core@7.23.6): - dependencies: - '@babel/core': 7.23.6 + '@types/babel__traverse': 7.20.6 + + babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.9): + dependencies: + '@babel/core': 7.24.9 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.9) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.9) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.9) + + babel-preset-jest@29.6.3(@babel/core@7.24.9): + dependencies: + '@babel/core': 7.24.9 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.6) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.9) backoff@2.5.0: dependencies: @@ -5022,7 +4999,7 @@ snapshots: bignumber.js@9.0.0: {} - binary-extensions@2.2.0: {} + binary-extensions@2.3.0: {} bl@4.1.0: dependencies: @@ -5030,23 +5007,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - body-parser@1.20.1: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - body-parser@1.20.2: dependencies: bytes: 3.1.2 @@ -5073,20 +5033,20 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@3.0.2: + braces@3.0.3: dependencies: - fill-range: 7.0.1 + fill-range: 7.1.1 brotli@1.3.3: dependencies: base64-js: 1.5.1 - browserslist@4.22.2: + browserslist@4.23.2: dependencies: - caniuse-lite: 1.0.30001570 - electron-to-chromium: 1.4.614 - node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.22.2) + caniuse-lite: 1.0.30001642 + electron-to-chromium: 1.4.830 + node-releases: 2.0.17 + update-browserslist-db: 1.1.0(browserslist@4.23.2) bs-logger@0.2.6: dependencies: @@ -5111,19 +5071,13 @@ snapshots: bytes@3.1.2: {} - call-bind@1.0.5: - dependencies: - function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.1.1 - call-bind@1.0.7: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 - set-function-length: 1.2.1 + set-function-length: 1.2.2 callsites@3.1.0: {} @@ -5131,9 +5085,13 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001570: {} + caniuse-lite@1.0.30001642: {} - centra@2.6.0: {} + centra@2.7.0: + dependencies: + follow-redirects: 1.15.6 + transitivePeerDependencies: + - debug chalk@2.4.2: dependencies: @@ -5154,10 +5112,10 @@ snapshots: chardet@0.7.0: {} - chokidar@3.5.3: + chokidar@3.6.0: dependencies: anymatch: 3.1.3 - braces: 3.0.2 + braces: 3.0.3 glob-parent: 5.1.2 is-binary-path: 2.1.0 is-glob: 4.0.3 @@ -5166,19 +5124,19 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - chrome-trace-event@1.0.3: {} + chrome-trace-event@1.0.4: {} ci-info@3.9.0: {} - cjs-module-lexer@1.2.3: {} + cjs-module-lexer@1.3.1: {} class-transformer@0.5.1: {} class-validator@0.14.1: dependencies: - '@types/validator': 13.11.8 - libphonenumber-js: 1.10.54 - validator: 13.11.0 + '@types/validator': 13.12.0 + libphonenumber-js: 1.11.4 + validator: 13.12.0 cli-cursor@2.1.0: dependencies: @@ -5190,7 +5148,7 @@ snapshots: cli-spinners@2.9.2: {} - cli-table3@0.6.3: + cli-table3@0.6.5: dependencies: string-width: 4.2.3 optionalDependencies: @@ -5280,7 +5238,7 @@ snapshots: cookie-signature@1.0.6: {} - cookie@0.5.0: {} + cookie@0.6.0: {} core-util-is@1.0.2: {} @@ -5342,32 +5300,32 @@ snapshots: dependencies: ms: 2.0.0 - debug@4.3.4: + debug@4.3.5: dependencies: ms: 2.1.2 - dedent@1.5.1: {} + dedent@1.5.3: {} deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.1 - call-bind: 1.0.5 + call-bind: 1.0.7 es-get-iterator: 1.1.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 is-arguments: 1.1.1 is-array-buffer: 3.0.4 is-date-object: 1.0.5 is-regex: 1.1.4 is-shared-array-buffer: 1.0.3 isarray: 2.0.5 - object-is: 1.1.5 + object-is: 1.1.6 object-keys: 1.1.1 object.assign: 4.1.5 regexp.prototype.flags: 1.5.2 - side-channel: 1.0.4 + side-channel: 1.0.6 which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.14 + which-collection: 1.0.2 + which-typed-array: 1.1.15 deep-is@0.1.4: {} @@ -5379,12 +5337,6 @@ snapshots: dependencies: clone: 1.0.4 - define-data-property@1.1.1: - dependencies: - get-intrinsic: 1.2.2 - gopd: 1.0.1 - has-property-descriptors: 1.0.1 - define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 @@ -5393,8 +5345,8 @@ snapshots: define-properties@1.2.1: dependencies: - define-data-property: 1.1.1 - has-property-descriptors: 1.0.1 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 delayed-stream@1.0.0: {} @@ -5403,7 +5355,7 @@ snapshots: destroy@1.2.0: {} - detect-libc@2.0.2: {} + detect-libc@2.0.3: {} detect-newline@3.1.0: {} @@ -5423,7 +5375,7 @@ snapshots: dotenv-expand@10.0.0: {} - dotenv@16.3.1: {} + dotenv@16.4.5: {} eastasianwidth@0.2.0: {} @@ -5433,7 +5385,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.4.614: {} + electron-to-chromium@1.4.830: {} emittery@0.13.1: {} @@ -5443,7 +5395,7 @@ snapshots: encodeurl@1.0.2: {} - enhanced-resolve@5.15.0: + enhanced-resolve@5.17.0: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 @@ -5465,19 +5417,19 @@ snapshots: es-get-iterator@1.1.3: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 is-arguments: 1.1.1 - is-map: 2.0.2 - is-set: 2.0.2 + is-map: 2.0.3 + is-set: 2.0.3 is-string: 1.0.7 isarray: 2.0.5 stop-iteration-iterator: 1.0.0 - es-module-lexer@1.4.1: {} + es-module-lexer@1.5.4: {} - escalade@3.1.1: {} + escalade@3.1.2: {} escape-html@1.0.3: {} @@ -5487,19 +5439,17 @@ snapshots: escape-string-regexp@4.0.0: {} - escape-string-regexp@5.0.0: {} - - eslint-config-prettier@8.10.0(eslint@8.56.0): + eslint-config-prettier@8.10.0(eslint@8.57.0): dependencies: - eslint: 8.56.0 + eslint: 8.57.0 - eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.56.0))(eslint@8.56.0)(prettier@2.8.8): + eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8): dependencies: - eslint: 8.56.0 + eslint: 8.57.0 prettier: 2.8.8 prettier-linter-helpers: 1.0.0 optionalDependencies: - eslint-config-prettier: 8.10.0(eslint@8.56.0) + eslint-config-prettier: 8.10.0(eslint@8.57.0) eslint-scope@5.1.1: dependencies: @@ -5513,26 +5463,26 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint@8.56.0: + eslint@8.57.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@eslint-community/regexpp': 4.10.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 - '@humanwhocodes/config-array': 0.11.13 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 + debug: 4.3.5 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.5.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -5540,7 +5490,7 @@ snapshots: glob-parent: 6.0.2 globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.3.0 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -5550,7 +5500,7 @@ snapshots: lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.3 + optionator: 0.9.4 strip-ansi: 6.0.1 text-table: 0.2.0 transitivePeerDependencies: @@ -5558,13 +5508,13 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.11.2 - acorn-jsx: 5.3.2(acorn@8.11.2) + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} - esquery@1.5.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -5604,14 +5554,14 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - express@4.18.2: + express@4.19.2: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.1 + body-parser: 1.20.2 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.5.0 + cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 @@ -5664,7 +5614,7 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.7 fast-json-stable-stringify@2.1.0: {} @@ -5672,11 +5622,11 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-xml-parser@4.3.6: + fast-xml-parser@4.4.0: dependencies: strnum: 1.0.5 - fastq@1.16.0: + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -5692,22 +5642,17 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - figures@5.0.0: - dependencies: - escape-string-regexp: 5.0.0 - is-unicode-supported: 1.3.0 - file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 - file-type@19.0.0: + file-type@19.2.0: dependencies: - readable-web-to-node-stream: 3.0.2 - strtok3: 7.0.0 - token-types: 5.0.1 + strtok3: 8.0.0 + token-types: 6.0.0 + uint8array-extras: 1.4.0 - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -5735,11 +5680,11 @@ snapshots: flat-cache@3.2.0: dependencies: - flatted: 3.2.9 + flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 - flatted@3.2.9: {} + flatted@3.3.1: {} follow-redirects@1.15.6: {} @@ -5759,16 +5704,16 @@ snapshots: dependencies: is-callable: 1.2.7 - foreground-child@3.1.1: + foreground-child@3.2.1: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.89.0): + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.92.1): dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.7 chalk: 4.1.2 - chokidar: 3.5.3 + chokidar: 3.6.0 cosmiconfig: 8.3.6(typescript@5.3.3) deepmerge: 4.3.1 fs-extra: 10.1.0 @@ -5776,10 +5721,10 @@ snapshots: minimatch: 3.1.2 node-abort-controller: 3.1.1 schema-utils: 3.3.0 - semver: 7.5.4 + semver: 7.6.3 tapable: 2.2.1 typescript: 5.3.3 - webpack: 5.89.0 + webpack: 5.92.1 form-data-lite@1.0.3: dependencies: @@ -5803,7 +5748,7 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 - fs-monkey@1.0.5: {} + fs-monkey@1.0.6: {} fs.realpath@1.0.0: {} @@ -5820,20 +5765,13 @@ snapshots: get-caller-file@2.0.5: {} - get-intrinsic@1.2.2: - dependencies: - function-bind: 1.1.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.0 - get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 + hasown: 2.0.2 get-package-type@0.1.0: {} @@ -5849,13 +5787,14 @@ snapshots: glob-to-regexp@0.4.1: {} - glob@10.3.10: + glob@10.4.2: dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.3 - minipass: 7.0.4 - path-scurry: 1.10.1 + foreground-child: 3.2.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 glob@7.2.3: dependencies: @@ -5866,13 +5805,6 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 - glob@9.3.5: - dependencies: - fs.realpath: 1.0.0 - minimatch: 8.0.4 - minipass: 4.2.8 - path-scurry: 1.10.1 - globals@11.12.0: {} globals@13.24.0: @@ -5884,13 +5816,13 @@ snapshots: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.3.0 + ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 gopd@1.0.1: dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 graceful-fs@4.2.11: {} @@ -5904,15 +5836,11 @@ snapshots: has-own-prop@2.0.0: {} - has-property-descriptors@1.0.1: - dependencies: - get-intrinsic: 1.2.2 - has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 - has-proto@1.0.1: {} + has-proto@1.0.3: {} has-symbols@1.0.3: {} @@ -5920,7 +5848,7 @@ snapshots: dependencies: has-symbols: 1.0.3 - hasown@2.0.0: + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -5946,7 +5874,7 @@ snapshots: ieee754@1.2.1: {} - ignore@5.3.0: {} + ignore@5.3.1: {} import-fresh@3.3.0: dependencies: @@ -6034,15 +5962,15 @@ snapshots: through: 2.3.8 wrap-ansi: 6.2.0 - inquirer@9.2.11: + inquirer@9.2.15: dependencies: - '@ljharb/through': 2.3.11 + '@ljharb/through': 2.3.13 ansi-escapes: 4.3.2 chalk: 5.3.0 cli-cursor: 3.1.0 cli-width: 4.1.0 external-editor: 3.1.0 - figures: 5.0.0 + figures: 3.2.0 lodash: 4.17.21 mute-stream: 1.0.0 ora: 5.4.1 @@ -6055,22 +5983,20 @@ snapshots: internal-slot@1.0.7: dependencies: es-errors: 1.3.0 - hasown: 2.0.0 - side-channel: 1.0.4 - - interpret@1.4.0: {} + hasown: 2.0.2 + side-channel: 1.0.6 ipaddr.js@1.9.1: {} is-arguments@1.1.1: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-tostringtag: 1.0.2 is-array-buffer@3.0.4: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-arrayish@0.2.1: {} @@ -6082,18 +6008,18 @@ snapshots: is-binary-path@2.1.0: dependencies: - binary-extensions: 2.2.0 + binary-extensions: 2.3.0 is-boolean-object@1.1.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-tostringtag: 1.0.2 is-callable@1.2.7: {} - is-core-module@2.13.1: + is-core-module@2.15.0: dependencies: - hasown: 2.0.0 + hasown: 2.0.2 is-date-object@1.0.5: dependencies: @@ -6113,7 +6039,7 @@ snapshots: is-interactive@1.0.0: {} - is-map@2.0.2: {} + is-map@2.0.3: {} is-number-object@1.0.7: dependencies: @@ -6125,10 +6051,10 @@ snapshots: is-regex@1.1.4: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-tostringtag: 1.0.2 - is-set@2.0.2: {} + is-set@2.0.3: {} is-shared-array-buffer@1.0.3: dependencies: @@ -6146,14 +6072,12 @@ snapshots: is-unicode-supported@0.1.0: {} - is-unicode-supported@1.3.0: {} + is-weakmap@2.0.2: {} - is-weakmap@2.0.1: {} - - is-weakset@2.0.2: + is-weakset@2.0.3: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 isarray@1.0.0: {} @@ -6165,21 +6089,21 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.23.6 - '@babel/parser': 7.23.6 + '@babel/core': 7.24.9 + '@babel/parser': 7.24.8 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color - istanbul-lib-instrument@6.0.1: + istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.23.6 - '@babel/parser': 7.23.6 + '@babel/core': 7.24.9 + '@babel/parser': 7.24.8 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -6191,20 +6115,20 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.4 + debug: 4.3.5 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color - istanbul-reports@3.1.6: + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 iterare@1.2.1: {} - jackspeak@2.3.6: + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: @@ -6225,7 +6149,7 @@ snapshots: '@types/node': 18.15.11 chalk: 4.1.2 co: 4.6.0 - dedent: 1.5.1 + dedent: 1.5.3 is-generator-fn: 2.1.0 jest-each: 29.7.0 jest-matcher-utils: 29.7.0 @@ -6235,7 +6159,7 @@ snapshots: jest-util: 29.7.0 p-limit: 3.1.0 pretty-format: 29.7.0 - pure-rand: 6.0.4 + pure-rand: 6.1.0 slash: 3.0.0 stack-utils: 2.0.6 transitivePeerDependencies: @@ -6263,10 +6187,10 @@ snapshots: jest-config@29.7.0(@types/node@18.15.11)(ts-node@10.9.2(@types/node@18.15.11)(typescript@4.9.5)): dependencies: - '@babel/core': 7.23.6 + '@babel/core': 7.24.9 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.23.6) + babel-jest: 29.7.0(@babel/core@7.24.9) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -6280,7 +6204,7 @@ snapshots: jest-runner: 29.7.0 jest-util: 29.7.0 jest-validate: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 parse-json: 5.2.0 pretty-format: 29.7.0 slash: 3.0.0 @@ -6333,7 +6257,7 @@ snapshots: jest-regex-util: 29.6.3 jest-util: 29.7.0 jest-worker: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.7 walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 @@ -6352,12 +6276,12 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.7 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 - micromatch: 4.0.5 + micromatch: 4.0.7 pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 @@ -6430,7 +6354,7 @@ snapshots: '@jest/types': 29.6.3 '@types/node': 18.15.11 chalk: 4.1.2 - cjs-module-lexer: 1.2.3 + cjs-module-lexer: 1.3.1 collect-v8-coverage: 1.0.2 glob: 7.2.3 graceful-fs: 4.2.11 @@ -6448,15 +6372,15 @@ snapshots: jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.23.6 - '@babel/generator': 7.23.6 - '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.6) - '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.6) - '@babel/types': 7.23.6 + '@babel/core': 7.24.9 + '@babel/generator': 7.24.10 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.9) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.9) + '@babel/types': 7.24.9 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.6) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.9) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -6467,7 +6391,7 @@ snapshots: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.5.4 + semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -6554,7 +6478,9 @@ snapshots: json5@2.2.3: {} - jsonc-parser@3.2.0: {} + jsonc-parser@3.2.1: {} + + jsonc-parser@3.3.1: {} jsonfile@6.1.0: dependencies: @@ -6573,7 +6499,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.5.4 + semver: 7.6.3 jwa@1.4.1: dependencies: @@ -6601,7 +6527,7 @@ snapshots: ldap-server-mock@6.0.1: dependencies: ldapjs: 2.3.3 - tslib: 2.6.2 + tslib: 2.6.3 ldapjs@2.3.3: dependencies: @@ -6614,14 +6540,13 @@ snapshots: vasync: 2.2.1 verror: 1.10.1 - ldapts@7.0.12: + ldapts@7.1.0: dependencies: '@types/asn1': 0.2.4 - '@types/uuid': 9.0.8 asn1: 0.2.6 - debug: 4.3.4 + debug: 4.3.5 strict-event-emitter-types: 2.0.0 - uuid: 9.0.1 + uuid: 10.0.0 transitivePeerDependencies: - supports-color @@ -6632,7 +6557,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - libphonenumber-js@1.10.54: {} + libphonenumber-js@1.11.4: {} lightcookie@1.0.25: {} @@ -6653,6 +6578,10 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash.escaperegexp@4.1.2: {} + + lodash.groupby@4.6.0: {} + lodash.includes@4.3.0: {} lodash.invoke@4.5.2: {} @@ -6663,12 +6592,16 @@ snapshots: lodash.isinteger@4.0.4: {} + lodash.isnil@4.0.0: {} + lodash.isnumber@3.0.3: {} lodash.isplainobject@4.0.6: {} lodash.isstring@4.0.1: {} + lodash.isundefined@3.0.1: {} + lodash.memoize@4.1.2: {} lodash.merge@4.6.2: {} @@ -6677,6 +6610,8 @@ snapshots: lodash.partialright@4.2.1: {} + lodash.uniq@4.5.0: {} + lodash@4.17.21: {} log-symbols@4.1.0: @@ -6684,23 +6619,19 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 - lru-cache@10.1.0: {} + lru-cache@10.4.3: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - magic-string@0.30.5: + magic-string@0.30.8: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 make-dir@4.0.0: dependencies: - semver: 7.5.4 + semver: 7.6.3 make-error@1.3.6: {} @@ -6716,7 +6647,7 @@ snapshots: memfs@3.5.3: dependencies: - fs-monkey: 1.0.5 + fs-monkey: 1.0.6 merge-descriptors@1.0.1: {} @@ -6726,9 +6657,9 @@ snapshots: methods@1.1.2: {} - micromatch@4.0.5: + micromatch@4.0.7: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 mime-db@1.52.0: {} @@ -6749,19 +6680,13 @@ snapshots: dependencies: brace-expansion: 1.1.11 - minimatch@8.0.4: - dependencies: - brace-expansion: 2.0.1 - - minimatch@9.0.3: + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 minimist@1.2.8: {} - minipass@4.2.8: {} - - minipass@7.0.4: {} + minipass@7.1.2: {} mkdirp@0.5.6: dependencies: @@ -6816,7 +6741,7 @@ snapshots: nock@13.5.4: dependencies: - debug: 4.3.4 + debug: 4.3.5 json-stringify-safe: 5.0.1 propagate: 2.0.1 transitivePeerDependencies: @@ -6834,7 +6759,7 @@ snapshots: node-int64@0.4.0: {} - node-releases@2.0.14: {} + node-releases@2.0.17: {} normalize-package-data@2.5.0: dependencies: @@ -6851,18 +6776,18 @@ snapshots: object-assign@4.1.1: {} - object-inspect@1.13.1: {} + object-inspect@1.13.2: {} - object-is@1.1.5: + object-is@1.1.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 object-keys@1.1.1: {} object.assign@4.1.5: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -6887,14 +6812,14 @@ snapshots: dependencies: klona: 2.0.6 - optionator@0.9.3: + optionator@0.9.4: dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 + word-wrap: 1.2.5 ora@5.4.1: dependencies: @@ -6928,9 +6853,11 @@ snapshots: p-try@2.2.0: {} - pactum-matchers@1.1.6: {} + package-json-from-dist@1.0.0: {} - pactum@3.6.0: + pactum-matchers@1.1.7: {} + + pactum@3.7.0: dependencies: '@exodus/schemasafe': 1.3.0 deep-override: 1.0.2 @@ -6939,10 +6866,12 @@ snapshots: klona: 2.0.6 lightcookie: 1.0.25 openapi-fuzzer-core: 1.0.6 - pactum-matchers: 1.1.6 + pactum-matchers: 1.1.7 parse-graphql: 1.0.0 - phin: 3.7.0 + phin: 3.7.1 polka: 0.5.2 + transitivePeerDependencies: + - debug pad@2.3.0: dependencies: @@ -6958,7 +6887,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -6972,7 +6901,7 @@ snapshots: passport-strategy@1.0.0: {} - passport@0.6.0: + passport@0.7.0: dependencies: passport-strategy: 1.0.0 pause: 0.0.1 @@ -6986,10 +6915,10 @@ snapshots: path-parse@1.0.7: {} - path-scurry@1.10.1: + path-scurry@1.11.1: dependencies: - lru-cache: 10.1.0 - minipass: 7.0.4 + lru-cache: 10.4.3 + minipass: 7.1.2 path-to-regexp@0.1.7: {} @@ -7006,17 +6935,19 @@ snapshots: linebreak: 1.1.0 png-js: 1.0.0 - peek-readable@5.0.0: {} + peek-readable@5.1.3: {} - phin@3.7.0: + phin@3.7.1: dependencies: - centra: 2.6.0 + centra: 2.7.0 + transitivePeerDependencies: + - debug - picocolors@1.0.0: {} + picocolors@1.0.1: {} picomatch@2.3.1: {} - picomatch@3.0.1: {} + picomatch@4.0.1: {} pirates@4.0.6: {} @@ -7051,11 +6982,11 @@ snapshots: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 18.2.0 + react-is: 18.3.1 - prisma@5.8.1: + prisma@5.17.0: dependencies: - '@prisma/engines': 5.8.1 + '@prisma/engines': 5.17.0 process-nextick-args@2.0.1: {} @@ -7075,11 +7006,11 @@ snapshots: punycode@2.3.1: {} - pure-rand@6.0.4: {} + pure-rand@6.1.0: {} qs@6.11.0: dependencies: - side-channel: 1.0.4 + side-channel: 1.0.6 queue-microtask@1.2.3: {} @@ -7089,13 +7020,6 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.1: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - raw-body@2.5.2: dependencies: bytes: 3.1.2 @@ -7103,7 +7027,7 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - react-is@18.2.0: {} + react-is@18.3.1: {} read-pkg-up@7.0.1: dependencies: @@ -7144,18 +7068,10 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readable-web-to-node-stream@3.0.2: - dependencies: - readable-stream: 3.6.2 - readdirp@3.6.0: dependencies: picomatch: 2.3.1 - rechoir@0.6.2: - dependencies: - resolve: 1.22.8 - reflect-metadata@0.1.14: {} regexp.prototype.flags@1.5.2: @@ -7183,7 +7099,7 @@ snapshots: resolve@1.22.8: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.15.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -7205,10 +7121,6 @@ snapshots: dependencies: glob: 7.2.3 - rimraf@4.4.1: - dependencies: - glob: 9.3.5 - run-async@2.4.1: {} run-async@3.0.0: {} @@ -7229,7 +7141,7 @@ snapshots: rxjs@7.8.1: dependencies: - tslib: 2.6.2 + tslib: 2.6.3 safe-buffer@5.1.2: {} @@ -7247,9 +7159,7 @@ snapshots: semver@6.3.1: {} - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 + semver@7.6.3: {} send@0.18.0: dependencies: @@ -7269,7 +7179,7 @@ snapshots: transitivePeerDependencies: - supports-color - serialize-javascript@6.0.1: + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -7282,21 +7192,14 @@ snapshots: transitivePeerDependencies: - supports-color - set-function-length@1.1.1: - dependencies: - define-data-property: 1.1.1 - get-intrinsic: 1.2.2 - gopd: 1.0.1 - has-property-descriptors: 1.0.1 - - set-function-length@1.2.1: + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 set-function-name@2.0.2: dependencies: @@ -7307,31 +7210,31 @@ snapshots: setprototypeof@1.2.0: {} - sharp@0.33.2: + sharp@0.33.4: dependencies: color: 4.2.3 - detect-libc: 2.0.2 - semver: 7.5.4 + detect-libc: 2.0.3 + semver: 7.6.3 optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.2 - '@img/sharp-darwin-x64': 0.33.2 - '@img/sharp-libvips-darwin-arm64': 1.0.1 - '@img/sharp-libvips-darwin-x64': 1.0.1 - '@img/sharp-libvips-linux-arm': 1.0.1 - '@img/sharp-libvips-linux-arm64': 1.0.1 - '@img/sharp-libvips-linux-s390x': 1.0.1 - '@img/sharp-libvips-linux-x64': 1.0.1 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 - '@img/sharp-libvips-linuxmusl-x64': 1.0.1 - '@img/sharp-linux-arm': 0.33.2 - '@img/sharp-linux-arm64': 0.33.2 - '@img/sharp-linux-s390x': 0.33.2 - '@img/sharp-linux-x64': 0.33.2 - '@img/sharp-linuxmusl-arm64': 0.33.2 - '@img/sharp-linuxmusl-x64': 0.33.2 - '@img/sharp-wasm32': 0.33.2 - '@img/sharp-win32-ia32': 0.33.2 - '@img/sharp-win32-x64': 0.33.2 + '@img/sharp-darwin-arm64': 0.33.4 + '@img/sharp-darwin-x64': 0.33.4 + '@img/sharp-libvips-darwin-arm64': 1.0.2 + '@img/sharp-libvips-darwin-x64': 1.0.2 + '@img/sharp-libvips-linux-arm': 1.0.2 + '@img/sharp-libvips-linux-arm64': 1.0.2 + '@img/sharp-libvips-linux-s390x': 1.0.2 + '@img/sharp-libvips-linux-x64': 1.0.2 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 + '@img/sharp-libvips-linuxmusl-x64': 1.0.2 + '@img/sharp-linux-arm': 0.33.4 + '@img/sharp-linux-arm64': 0.33.4 + '@img/sharp-linux-s390x': 0.33.4 + '@img/sharp-linux-x64': 0.33.4 + '@img/sharp-linuxmusl-arm64': 0.33.4 + '@img/sharp-linuxmusl-x64': 0.33.4 + '@img/sharp-wasm32': 0.33.4 + '@img/sharp-win32-ia32': 0.33.4 + '@img/sharp-win32-x64': 0.33.4 shebang-command@2.0.0: dependencies: @@ -7339,17 +7242,12 @@ snapshots: shebang-regex@3.0.0: {} - shelljs@0.8.5: + side-channel@1.0.6: dependencies: - glob: 7.2.3 - interpret: 1.4.0 - rechoir: 0.6.2 - - side-channel@1.0.4: - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - object-inspect: 1.13.1 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 signal-exit@3.0.7: {} @@ -7384,16 +7282,16 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.16 + spdx-license-ids: 3.0.18 - spdx-exceptions@2.3.0: {} + spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.16 + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 - spdx-license-ids@3.0.16: {} + spdx-license-ids@3.0.18: {} sprintf-js@1.0.3: {} @@ -7465,10 +7363,10 @@ snapshots: strnum@1.0.5: {} - strtok3@7.0.0: + strtok3@8.0.0: dependencies: '@tokenizer/token': 0.3.0 - peek-readable: 5.0.0 + peek-readable: 5.1.3 supports-color@5.5.0: dependencies: @@ -7484,7 +7382,7 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - swagger-ui-dist@5.11.0: {} + swagger-ui-dist@5.17.14: {} symbol-observable@1.0.1: {} @@ -7492,19 +7390,19 @@ snapshots: tapable@2.2.1: {} - terser-webpack-plugin@5.3.9(webpack@5.89.0): + terser-webpack-plugin@5.3.10(webpack@5.92.1): dependencies: - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 - serialize-javascript: 6.0.1 - terser: 5.26.0 - webpack: 5.89.0 + serialize-javascript: 6.0.2 + terser: 5.31.3 + webpack: 5.92.1 - terser@5.26.0: + terser@5.31.3: dependencies: - '@jridgewell/source-map': 0.3.5 - acorn: 8.11.2 + '@jridgewell/source-map': 0.3.6 + acorn: 8.12.1 commander: 2.20.3 source-map-support: 0.5.21 @@ -7534,7 +7432,7 @@ snapshots: toidentifier@1.0.1: {} - token-types@5.0.1: + token-types@6.0.0: dependencies: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 @@ -7547,7 +7445,7 @@ snapshots: dependencies: matchit: 1.1.0 - ts-jest@29.1.0(@babel/core@7.23.6)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.6))(jest@29.5.0(@types/node@18.15.11)(ts-node@10.9.2(@types/node@18.15.11)(typescript@4.9.5)))(typescript@4.9.5): + ts-jest@29.1.0(@babel/core@7.24.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.5.0(@types/node@18.15.11)(ts-node@10.9.2(@types/node@18.15.11)(typescript@4.9.5)))(typescript@4.9.5): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -7556,34 +7454,34 @@ snapshots: json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.5.4 + semver: 7.6.3 typescript: 4.9.5 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.23.6 + '@babel/core': 7.24.9 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.23.6) + babel-jest: 29.7.0(@babel/core@7.24.9) - ts-loader@9.5.1(typescript@4.9.5)(webpack@5.89.0): + ts-loader@9.5.1(typescript@4.9.5)(webpack@5.92.1): dependencies: chalk: 4.1.2 - enhanced-resolve: 5.15.0 - micromatch: 4.0.5 - semver: 7.5.4 + enhanced-resolve: 5.17.0 + micromatch: 4.0.7 + semver: 7.6.3 source-map: 0.7.4 typescript: 4.9.5 - webpack: 5.89.0 + webpack: 5.92.1 ts-node@10.9.2(@types/node@18.15.11)(typescript@4.9.5): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 + '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 18.15.11 - acorn: 8.11.2 - acorn-walk: 8.3.1 + acorn: 8.12.1 + acorn-walk: 8.3.3 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 @@ -7595,7 +7493,7 @@ snapshots: tsconfig-paths-webpack-plugin@4.1.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.15.0 + enhanced-resolve: 5.17.0 tsconfig-paths: 4.2.0 tsconfig-paths@4.2.0: @@ -7606,7 +7504,7 @@ snapshots: tslib@1.14.1: {} - tslib@2.6.2: {} + tslib@2.6.3: {} tsutils@3.21.0(typescript@4.9.5): dependencies: @@ -7642,6 +7540,8 @@ snapshots: dependencies: '@lukeed/csprng': 1.1.0 + uint8array-extras@1.4.0: {} + unicode-properties@1.4.1: dependencies: base64-js: 1.5.1 @@ -7656,11 +7556,11 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.0.13(browserslist@4.22.2): + update-browserslist-db@1.1.0(browserslist@4.23.2): dependencies: - browserslist: 4.22.2 - escalade: 3.1.1 - picocolors: 1.0.0 + browserslist: 4.23.2 + escalade: 3.1.2 + picocolors: 1.0.1 uri-js@4.4.1: dependencies: @@ -7670,15 +7570,13 @@ snapshots: utils-merge@1.0.1: {} - uuid@9.0.0: {} - - uuid@9.0.1: {} + uuid@10.0.0: {} v8-compile-cache-lib@3.0.1: {} - v8-to-istanbul@9.2.0: + v8-to-istanbul@9.3.0: dependencies: - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 @@ -7687,7 +7585,7 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - validator@13.11.0: {} + validator@13.12.0: {} vary@1.1.2: {} @@ -7711,7 +7609,7 @@ snapshots: dependencies: makeerror: 1.0.12 - watchpack@2.4.0: + watchpack@2.4.1: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -7726,19 +7624,19 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.89.0: + webpack@5.92.1: dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.5 - '@webassemblyjs/ast': 1.11.6 - '@webassemblyjs/wasm-edit': 1.11.6 - '@webassemblyjs/wasm-parser': 1.11.6 - acorn: 8.11.2 - acorn-import-assertions: 1.9.0(acorn@8.11.2) - browserslist: 4.22.2 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.15.0 - es-module-lexer: 1.4.1 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/wasm-edit': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + acorn: 8.12.1 + acorn-import-attributes: 1.9.5(acorn@8.12.1) + browserslist: 4.23.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.17.0 + es-module-lexer: 1.5.4 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -7749,8 +7647,8 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.9(webpack@5.89.0) - watchpack: 2.4.0 + terser-webpack-plugin: 5.3.10(webpack@5.92.1) + watchpack: 2.4.1 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' @@ -7770,17 +7668,17 @@ snapshots: is-string: 1.0.7 is-symbol: 1.0.4 - which-collection@1.0.1: + which-collection@1.0.2: dependencies: - is-map: 2.0.2 - is-set: 2.0.2 - is-weakmap: 2.0.1 - is-weakset: 2.0.2 + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 - which-typed-array@1.1.14: + which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.2 @@ -7789,6 +7687,8 @@ snapshots: dependencies: isexe: 2.0.0 + word-wrap@1.2.5: {} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -7820,14 +7720,12 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} - yargs-parser@21.1.1: {} yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ddc9f4b..0c0a70b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,12 +21,12 @@ model Asso { descriptionShortTranslationId String @unique descriptionTranslationId String @unique - descriptionShortTranslation Translation @relation(name: "descriptionShortTranslation", fields: [descriptionShortTranslationId], references: [id], onDelete: Cascade) - descriptionTranslation Translation @relation(name: "descriptionTranslation", fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + descriptionShortTranslation Translation @relation(name: "descriptionShortTranslation", fields: [descriptionShortTranslationId], references: [id], onDelete: Cascade) + descriptionTranslation Translation @relation(name: "descriptionTranslation", fields: [descriptionTranslationId], references: [id], onDelete: Cascade) assoMemberships AssoMembership[] assoMessages AssoMessage[] events Event[] - assoMembershipRoles AssoMembershipRole[] + assoMembershipRoles AssoMembershipRole[] } model AssoMembership { @@ -55,10 +55,10 @@ model AssoMembershipRole { name String position Int isPresident Boolean - assoId String + assoId String assoMembership AssoMembership[] - asso Asso @relation(fields: [assoId], references: [id]) + asso Asso @relation(fields: [assoId], references: [id]) } model AssoMessage { @@ -127,7 +127,7 @@ model Semester { start DateTime @db.Date end DateTime @db.Date - openedUes Ue[] + openedUes Ueof[] annals UeAnnal[] comments UeComment[] courses UeCourse[] @@ -190,49 +190,65 @@ model Translation { de String? @db.Text zh String? @db.Text - assoDescriptionShort Asso? @relation("descriptionShortTranslation") assoDescription Asso? @relation("descriptionTranslation") + assoDescriptionShort Asso? @relation("descriptionShortTranslation") assoMessageTitle AssoMessage? @relation("titleTranslation") assoMessageTitleBody AssoMessage? @relation("bodyTranslation") eventDescription Event? @relation("descriptionTranslation") eventTitle Event? @relation("titleTranslation") - userPermissionName UserPermission? @relation("userPermissionName") + ueofInfo UeofInfo? @relation("ueofInfoObjectivesTranslation") + ueofInfoPrograms UeofInfo? @relation("ueofInfoProgramTranslation") userPermissionDescription UserPermission? @relation("userPermissionDescription") + userPermissionName UserPermission? @relation("userPermissionName") annalReportReasonDescriptions UeAnnalReportReason? - commentReportReasonDescriptions UeCommentReportReason? - starCriterionDescriptions UeStarCriterion? branchDescriptions UTTBranch? branchOptionDescriptions UTTBranchOption? + commentReportReasonDescriptions UeCommentReportReason? formationDescriptions UTTFormation? formationFollowingMethodDescriptions UTTFormationFollowingMethod? - ueNames Ue? - ueInfoComments UeInfo? @relation("ueInfoCommentsTranslation") - ueInfo UeInfo? @relation("ueInfoObjectivesTranslation") - ueInfoPrograms UeInfo? @relation("ueInfoProgramTranslation") + starCriterionDescriptions UeStarCriterion? + ueNames Ueof? } model Ue { - id String @id @default(uuid()) - code String @unique @db.VarChar(10) - inscriptionCode String @unique @db.Char(4) - nameTranslationId String @unique - validationRate Float? - ueInfoId String @unique + code String @id @db.VarChar(8) + createdAt DateTime @default(now()) + + subsequentUes Ueof[] @relation("ueRequirements") + aliases UeAlias[] + ueofs Ueof[] +} + +model UeAlias { + code String @id @db.VarChar(8) + standsFor String? @db.VarChar(8) + + alias Ue? @relation(fields: [standsFor], references: [code]) +} + +model Ueof { + code String @id @db.VarChar(20) + siepId Int @unique + + available Boolean @default(false) createdAt DateTime @default(now()) + nameTranslationId String @unique + ueId String + ueofInfoId String @unique updatedAt DateTime @updatedAt + info UeofInfo @relation(fields: [ueofInfoId], references: [id], onDelete: Cascade) name Translation @relation(fields: [nameTranslationId], references: [id], onDelete: Cascade) - usersSubscriptions UserUeSubscription[] - credits UeCredit[] - starVotes UeStarVote[] - openSemester Semester[] - workTime UeWorkTime? - info UeInfo @relation(fields: [ueInfoId], references: [id], onDelete: Cascade) - subsequentUes UeInfo[] @relation("ueRequirements") + requirements Ue[] @relation(name: "ueRequirements") + ue Ue @relation(fields: [ueId], references: [code]) annals UeAnnal[] comments UeComment[] courses UeCourse[] - branchOption UTTBranchOption[] + credits UeCredit[] + openSemester Semester[] + starVotes UeStarVote[] + usersSubscriptions UserUeSubscription[] + workTime UeWorkTime? } model UeAnnal { @@ -242,16 +258,16 @@ model UeAnnal { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? - validatedAt DateTime? - ueId String - senderId String? semesterId String + senderId String? typeId String + ueofId String + validatedAt DateTime? - ue Ue @relation(fields: [ueId], references: [id], onDelete: Cascade) + semester Semester @relation(fields: [semesterId], references: [code]) sender User? @relation(fields: [senderId], references: [id], onDelete: SetNull) type UeAnnalType @relation(fields: [typeId], references: [id]) - semester Semester @relation(fields: [semesterId], references: [code]) + ueof Ueof @relation(fields: [ueofId], references: [code], onDelete: Cascade) reports UeAnnalReport[] } @@ -264,16 +280,16 @@ model UeAnnalType { model UeAnnalReport { id String @id @default(uuid()) + annalId String body String? @db.Text createdAt DateTime @default(now()) mitigated Boolean @default(false) - annalId String - userId String? reasonId String + userId String? annal UeAnnal @relation(fields: [annalId], references: [id], onDelete: Cascade) - user User? @relation(fields: [userId], references: [id], onDelete: SetNull) reason UeAnnalReportReason @relation(fields: [reasonId], references: [name]) + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) @@unique([userId, annalId, reasonId]) // Prevent from spams } @@ -295,14 +311,14 @@ model UeComment { // Removed @updatedAt because the property is used to display the last datetime the content of the comment was altered on deletedAt DateTime? validatedAt DateTime? - lastValidatedBody String? - ueId String authorId String? + lastValidatedBody String? semesterId String + ueofId String - ue Ue @relation(fields: [ueId], references: [id], onDelete: Cascade) author User? @relation(fields: [authorId], references: [id], onDelete: SetNull) semester Semester @relation(fields: [semesterId], references: [code]) + ueof Ueof @relation(fields: [ueofId], references: [code], onDelete: Cascade) answers UeCommentReply[] reports UeCommentReport[] upvotes UeCommentUpvote[] @@ -318,8 +334,8 @@ model UeCommentReply { commentId String authorId String? - comment UeComment @relation(fields: [commentId], references: [id], onDelete: Cascade) author User? @relation(fields: [authorId], references: [id], onDelete: SetNull) + comment UeComment @relation(fields: [commentId], references: [id], onDelete: Cascade) reports UeCommentReplyReport[] } @@ -329,12 +345,12 @@ model UeCommentReport { createdAt DateTime @default(now()) mitigated Boolean @default(false) commentId String - userId String reasonId String + userId String comment UeComment @relation(fields: [commentId], references: [id], onDelete: Cascade) - user User @relation(fields: [userId], references: [id], onDelete: Cascade) reason UeCommentReportReason @relation(fields: [reasonId], references: [name], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([userId, commentId, reasonId]) // Prevent from spam } @@ -344,13 +360,13 @@ model UeCommentReplyReport { body String @db.Text createdAt DateTime @default(now()) mitigated Boolean @default(false) + reasonId String replyId String userId String - reasonId String + reason UeCommentReportReason @relation(fields: [reasonId], references: [name], onDelete: Cascade) reply UeCommentReply @relation(fields: [replyId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) - reason UeCommentReportReason @relation(fields: [reasonId], references: [name], onDelete: Cascade) @@unique([userId, replyId, reasonId]) // Prevent from spam } @@ -360,46 +376,46 @@ model UeCommentReportReason { descriptionTranslationId String @unique descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - reports UeCommentReport[] replyReports UeCommentReplyReport[] + reports UeCommentReport[] } model UeCommentUpvote { id String @id @default(uuid()) - userId String? commentId String createdAt DateTime @default(now()) + userId String? - user User? @relation(fields: [userId], references: [id], onDelete: SetNull) comment UeComment @relation(fields: [commentId], references: [id], onDelete: Cascade) + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) } model UeCourse { id String @id @default(uuid()) - type CourseType - room String @db.VarChar(50) createdAt DateTime @default(now()) - ueId String + room String @db.VarChar(50) semesterId String + type CourseType + ueofId String - students User[] - ue Ue @relation(fields: [ueId], references: [id]) - semester Semester @relation(fields: [semesterId], references: [code]) courseExchangesFrom UeCourseExchange[] @relation(name: "courseFrom") courseExchangesTo UeCourseExchange[] @relation(name: "courseTo") + semester Semester @relation(fields: [semesterId], references: [code]) + ueof Ueof @relation(fields: [ueofId], references: [code]) + students User[] timetableEntries TimetableEntry[] } model UeCourseExchange { id String @id @default(uuid()) - stillAvailable Boolean - body String? @db.Text - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime? authorId String + body String? @db.Text courseFromId String courseToId String + createdAt DateTime @default(now()) + deletedAt DateTime? + stillAvailable Boolean + updatedAt DateTime @updatedAt author User @relation(fields: [authorId], references: [id]) courseFrom UeCourse @relation(name: "courseFrom", fields: [courseFromId], references: [id]) @@ -409,48 +425,45 @@ model UeCourseExchange { model UeCourseExchangeReply { id String @id @default(uuid()) + authorId String body String @db.Text createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt deletedAt DateTime? - authorId String exchangeId String + updatedAt DateTime @updatedAt author User @relation(fields: [authorId], references: [id]) exchange UeCourseExchange @relation(fields: [exchangeId], references: [id]) } model UeCredit { - id String @id @default(uuid()) - credits Int @db.SmallInt - ueId String - categoryId String + id String @id @default(uuid()) + categoryId String? + credits Int @db.SmallInt + ueofId String - ue Ue @relation(fields: [ueId], references: [id], onDelete: Cascade) - category UeCreditCategory @relation(fields: [categoryId], references: [code]) + category UeCreditCategory? @relation(fields: [categoryId], references: [code]) + ueof Ueof @relation(fields: [ueofId], references: [code], onDelete: Cascade) + branchOptions UTTBranchOption[] } model UeCreditCategory { - code String @id @db.VarChar(10) + code String @id @db.Char(2) name String @db.VarChar(255) - credits UeCredit[] + ueCredits UeCredit[] } -model UeInfo { +model UeofInfo { id String @id @default(uuid()) - degree String? @db.Text minors String? @db.Text - languages String? @db.Text - commentTranslationId String? @unique + language String? @db.Text objectivesTranslationId String? @unique programTranslationId String? @unique - ue Ue? - comment Translation? @relation("ueInfoCommentsTranslation", fields: [commentTranslationId], references: [id], onDelete: Cascade) - objectives Translation? @relation("ueInfoObjectivesTranslation", fields: [objectivesTranslationId], references: [id], onDelete: Cascade) - program Translation? @relation("ueInfoProgramTranslation", fields: [programTranslationId], references: [id], onDelete: Cascade) - requirements Ue[] @relation(name: "ueRequirements") + objectives Translation? @relation("ueofInfoObjectivesTranslation", fields: [objectivesTranslationId], references: [id], onDelete: Cascade) + program Translation? @relation("ueofInfoProgramTranslation", fields: [programTranslationId], references: [id], onDelete: Cascade) + ueof Ueof? } model UeStarCriterion { @@ -466,28 +479,28 @@ model UeStarVote { id String @id @default(uuid()) value Int @db.SmallInt createdAt DateTime @default(now()) - ueId String criterionId String + ueofId String userId String? - ue Ue @relation(fields: [ueId], references: [id], onDelete: Cascade) criterion UeStarCriterion @relation(fields: [criterionId], references: [id], onDelete: Cascade) + ueof Ueof @relation(fields: [ueofId], references: [code], onDelete: Cascade) user User? @relation(fields: [userId], references: [id], onDelete: SetNull) - @@unique([ueId, userId, criterionId]) + @@unique([ueofId, userId, criterionId]) } model UeWorkTime { - id String @id @default(uuid()) + id String @id @default(uuid()) cm Int? td Int? tp Int? the Int? - project Int? + project Boolean? internship Int? - ueId String @unique + ueofId String @unique - ue Ue @relation(fields: [ueId], references: [id], onDelete: Cascade) + ueof Ueof @relation(fields: [ueofId], references: [code], onDelete: Cascade) } model UserPermission { @@ -525,21 +538,21 @@ model User { infosId String @unique mailsPhonesId String @unique socialNetworkId String @unique - privacyId String @unique + privacyId String @unique + socialNetwork UserSocialNetwork @relation(fields: [socialNetworkId], references: [id]) + rgpd UserRGPD @relation(fields: [rgpdId], references: [id]) + preference UserPreference @relation(fields: [preferenceId], references: [id]) + infos UserInfos @relation(fields: [infosId], references: [id]) + mailsPhones UserMailsPhones @relation(fields: [mailsPhonesId], references: [id]) userType UserType timestamps UserTimestamps? - socialNetwork UserSocialNetwork @relation(fields: [socialNetworkId], references: [id]) bans UserBan[] - rgpd UserRGPD @relation(fields: [rgpdId], references: [id]) bdeContributions UserBDEContribution[] assoMembership AssoMembership[] branchSubscriptions UserBranchSubscription[] formation UserFormation? - preference UserPreference @relation(fields: [preferenceId], references: [id]) - infos UserInfos @relation(fields: [infosId], references: [id]) addresses UserAddress[] - mailsPhones UserMailsPhones @relation(fields: [mailsPhonesId], references: [id]) otherAttributes UserOtherAttributValue[] UesSubscriptions UserUeSubscription[] UeStarVotes UeStarVote[] @@ -599,15 +612,15 @@ model UserBDEContribution { } model UserBranchSubscription { - id String @id @default(uuid()) - userId String - semesterNumber Int @db.SmallInt - createdAt DateTime @default(now()) - branchOptionId String - semesterCode String + id String @id @default(uuid()) + userId String + semesterNumber Int @db.SmallInt + createdAt DateTime @default(now()) + branchOptionId String + semesterCode String user User @relation(fields: [userId], references: [id]) - branchOption UTTBranchOption @relation(fields: [branchOptionId], references: [id]) + branchOption UTTBranchOption @relation(fields: [branchOptionId], references: [code]) semester Semester @relation(fields: [semesterCode], references: [code]) } @@ -701,11 +714,11 @@ model UserHomepageWidget { } model UserPreference { - id String @id @default(uuid()) - language Language @default(fr) - wantDaymail Boolean @default(false) - wantDayNotif Boolean @default(false) - wantDiscordUtt Boolean @default(false) + id String @id @default(uuid()) + language Language @default(fr) + wantDaymail Boolean @default(false) + wantDayNotif Boolean @default(false) + wantDiscordUtt Boolean @default(false) user User? } @@ -719,14 +732,14 @@ model UserRGPD { } model UserSocialNetwork { - id String @id @default(uuid()) - facebook String? @db.VarChar(255) - twitter String? @db.VarChar(255) - instagram String? @db.VarChar(255) - linkedin String? @db.VarChar(255) - twitch String? @db.VarChar(255) - spotify String? @db.VarChar(255) - discord String? @db.VarChar(255) + id String @id @default(uuid()) + facebook String? @db.VarChar(255) + twitter String? @db.VarChar(255) + instagram String? @db.VarChar(255) + linkedin String? @db.VarChar(255) + twitch String? @db.VarChar(255) + spotify String? @db.VarChar(255) + discord String? @db.VarChar(255) user User? } @@ -758,39 +771,39 @@ model UserUeSubscription { id String @id @default(uuid()) createdAt DateTime @default(now()) userId String - ueId String + ueofId String semesterId String user User @relation(fields: [userId], references: [id]) - ue Ue @relation(fields: [ueId], references: [id]) + ueof Ueof @relation(fields: [ueofId], references: [code]) semester Semester @relation(fields: [semesterId], references: [code]) - @@unique([userId, ueId, semesterId]) + @@unique([userId, ueofId, semesterId]) } model UTTBranch { - code String @id @db.VarChar(10) - name String @db.VarChar(255) + code String @id @db.VarChar(10) + name String @db.VarChar(255) + isMaster Boolean @default(false) exitSalary Int? employmentRate Float? CDIRate Float? abroadEmploymentRate Float? - descriptionTranslationId String @unique + descriptionTranslationId String @unique descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) branchOptions UTTBranchOption[] } model UTTBranchOption { - id String @id @default(uuid()) - code String @db.VarChar(10) + code String @id @db.VarChar(10) name String @db.VarChar(255) branchCode String descriptionTranslationId String @unique branch UTTBranch @relation(fields: [branchCode], references: [code]) descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - ues Ue[] + uecredits UeCredit[] branchSubscriptions UserBranchSubscription[] @@unique([code, branchCode]) diff --git a/prisma/seed/modules/ue.seed.ts b/prisma/seed/modules/ue.seed.ts index 1bf3f08..3efc1fe 100644 --- a/prisma/seed/modules/ue.seed.ts +++ b/prisma/seed/modules/ue.seed.ts @@ -5,6 +5,8 @@ import { generateTranslation } from '../utils'; const FAKER_ROUNDS = 20; +export const OF_SUFFIX = '_FR_TRO_U23'; + export default function ueSeed( prisma: PrismaClient, semesters: RawSemester[], @@ -22,49 +24,52 @@ export default function ueSeed( prisma.ue.create({ data: { code, - inscriptionCode: code.length === 3 ? `${code}X` : code.length === 4 ? code : code.substring(0, 4), - name: generateTranslation(faker.name.jobTitle), - validationRate: faker.datatype.number({ min: 0, max: 100 }), - createdAt: date, - updatedAt: date, - info: { + ueofs: { create: { - comment: generateTranslation(), - program: generateTranslation(), - objectives: generateTranslation(), - languages: faker.random.word(), - }, - }, - credits: { - create: [ - { - category: { - connect: { - code: faker.helpers.arrayElement(creditCategory).code, + code: `${code}${OF_SUFFIX}`, + siepId: faker.datatype.number({ min: 100000, max: 999999 }), + name: generateTranslation(faker.name.jobTitle), + createdAt: date, + updatedAt: date, + info: { + create: { + program: generateTranslation(), + objectives: generateTranslation(), + language: faker.random.word(), + }, + }, + credits: { + create: [ + { + category: { + connect: { + code: faker.helpers.arrayElement(creditCategory).code, + }, + }, + credits: faker.datatype.number({ min: 1, max: 6 }), + branchOptions: { + connect: faker.helpers + .arrayElements(branchOptions, faker.datatype.number({ min: 1, max: 3 })) + .map((branchOption) => ({ code: branchOption.code })), + }, }, + ], + }, + openSemester: { + connect: faker.helpers + .arrayElements(semesters, faker.datatype.number({ min: 1, max: 50 })) + .map((semester) => ({ code: semester.code })), + }, + workTime: { + create: { + cm: faker.datatype.number({ min: 6, max: 32 }), + td: faker.datatype.number({ min: 6, max: 32 }), + tp: faker.datatype.number({ min: 6, max: 16 }), + the: faker.datatype.number({ min: 32, max: 64 }), + project: faker.datatype.boolean(), + internship: 0, }, - credits: faker.datatype.number({ min: 1, max: 6 }), }, - ], - }, - openSemester: { - connect: faker.helpers - .arrayElements(semesters, faker.datatype.number({ min: 1, max: 50 })) - .map((semester) => ({ code: semester.code })), - }, - branchOption: { - connect: faker.helpers - .arrayElements(branchOptions, faker.datatype.number({ min: 1, max: 3 })) - .map((branchOption) => ({ id: branchOption.id })), - }, - workTime: { - create: { - cm: faker.datatype.number({ min: 6, max: 32 }), - td: faker.datatype.number({ min: 6, max: 32 }), - tp: faker.datatype.number({ min: 6, max: 16 }), - the: faker.datatype.number({ min: 32, max: 64 }), - project: faker.datatype.number({ min: 16, max: 48 }), - internship: 0, }, }, }, diff --git a/prisma/seed/modules/ueComment.seed.ts b/prisma/seed/modules/ueComment.seed.ts index 3c6dcf7..c3d91ba 100644 --- a/prisma/seed/modules/ueComment.seed.ts +++ b/prisma/seed/modules/ueComment.seed.ts @@ -1,4 +1,4 @@ -import { RawSemester, RawUe, RawUeComment, RawUser, RawUserUeSubscription } from '../../../src/prisma/types'; +import { RawSemester, RawUeComment, RawUser, RawUserUeSubscription } from '../../../src/prisma/types'; import { Prisma, PrismaClient } from '@prisma/client'; import { faker } from '@faker-js/faker'; @@ -7,7 +7,6 @@ const FAKER_ROUNDS = 100; export default function ueCommentSeed( prisma: PrismaClient, users: RawUser[], - ues: RawUe[], semester: RawSemester[], ueSubscriptions: RawUserUeSubscription[], ): Promise { @@ -38,9 +37,9 @@ export default function ueCommentSeed( id: subscription.userId, }, }, - ue: { + ueof: { connect: { - id: subscription.ueId, + code: subscription.ueofId, }, }, semester: { diff --git a/prisma/seed/modules/ueStarVotes.seed.ts b/prisma/seed/modules/ueStarVotes.seed.ts index 84db589..47174d6 100644 --- a/prisma/seed/modules/ueStarVotes.seed.ts +++ b/prisma/seed/modules/ueStarVotes.seed.ts @@ -17,7 +17,7 @@ export default function ueStarVotesSeed( prisma.ueStarVote.create({ data: { user: { connect: { id: subscription.userId } }, - ue: { connect: { id: subscription.ueId } }, + ueof: { connect: { code: subscription.ueofId } }, criterion: { connect: { id: criterion.id } }, value: faker.datatype.number({ min: 1, max: 5 }), }, diff --git a/prisma/seed/modules/ueSubscription.seed.ts b/prisma/seed/modules/ueSubscription.seed.ts index 5190257..97108a4 100644 --- a/prisma/seed/modules/ueSubscription.seed.ts +++ b/prisma/seed/modules/ueSubscription.seed.ts @@ -1,6 +1,7 @@ import { RawSemester, RawUe, RawUser, RawUserUeSubscription } from '../../../src/prisma/types'; import { PrismaClient } from '@prisma/client'; import { faker } from '@faker-js/faker'; +import { OF_SUFFIX } from './ue.seed'; export default function ueSubscriptionSeed( prisma: PrismaClient, @@ -16,7 +17,7 @@ export default function ueSubscriptionSeed( subscriptions.push( prisma.userUeSubscription.create({ data: { - ue: { connect: { id: ue.id } }, + ueof: { connect: { code: `${ue.code}$${OF_SUFFIX}` } }, user: { connect: { id: user.id } }, semester: { connect: { code: faker.helpers.arrayElement(semesters).code } }, }, diff --git a/prisma/seed/seed.ts b/prisma/seed/seed.ts index 130d02d..548e025 100644 --- a/prisma/seed/seed.ts +++ b/prisma/seed/seed.ts @@ -29,7 +29,7 @@ async function main() { const ues = await ueSeed(prisma, semesters, branchOptions, creditCategories); const users = await userSeed(prisma); const ueSubscriptions = await ueSubscriptionSeed(prisma, users, ues, semesters); - await ueCommentSeed(prisma, users, ues, semesters, ueSubscriptions); + await ueCommentSeed(prisma, users, semesters, ueSubscriptions); const ueStarCriterions = await ueStarCriterionSeed(prisma); await ueStarVotesSeed(prisma, ueStarCriterions, ueSubscriptions); const assos = await assoSeed(prisma); diff --git a/scripts/seed/aliases.ts b/scripts/seed/aliases.ts new file mode 100644 index 0000000..0865560 --- /dev/null +++ b/scripts/seed/aliases.ts @@ -0,0 +1,26 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +async function main() { + console.info('\x1b[42;30mSeeding UE aliases\x1b[0m'); + await prisma.ueAlias.deleteMany(); + await prisma.ueAlias.createMany({ + data: [ + { + code: 'EC01', + }, + { + code: 'MATH03', + standsFor: 'MT03', + }, + { + code: 'NF05', + standsFor: 'NF06', + }, + ], + }); + console.info('\x1b[42;30m✅ Aliases have been created\x1b[0m'); +} + +main(); diff --git a/scripts/seed/base.ts b/scripts/seed/base.ts new file mode 100644 index 0000000..c274660 --- /dev/null +++ b/scripts/seed/base.ts @@ -0,0 +1,182 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +async function main() { + // SEMESTERS // + await prisma.semester.deleteMany({}); + await prisma.semester.create({ + data: { + code: 'A24', + start: new Date('2024-08-31'), + end: new Date('2025-01-20'), + }, + }); + await prisma.semester.create({ + data: { + code: 'H24', + start: new Date('2025-01-21'), + end: new Date('2025-02-14'), + }, + }); + await prisma.semester.create({ + data: { + code: 'P25', + start: new Date('2025-02-15'), + end: new Date('2025-06-29'), + }, + }); + await prisma.semester.create({ + data: { + code: 'E25', + start: new Date('2025-07-01'), + end: new Date('2025-08-30'), + }, + }); + await prisma.semester.create({ + data: { + code: 'U24', + start: new Date('2024-08-31'), + end: new Date('2025-06-29'), + }, + }); + + // UE CATEGORIES // + console.log('Updating UE Categories'); + const categories = [ + { code: 'CS', name: 'Connaissances scientifiques' }, + { code: 'TM', name: 'Techniques et méthodes' }, + { code: 'ST', name: 'Stage' }, + { code: 'HT', name: 'Humanités et technologies' }, + { code: 'ME', name: 'Mise en situation' }, + { code: 'EC', name: 'Expression et communication' }, + { code: 'AC', name: 'Autres Crédits' }, + { code: 'MA', name: 'Master' }, + ]; + await Promise.all( + categories.map((category) => + prisma.ueCreditCategory.upsert({ + where: { + code: category.code, + }, + update: category, + create: category, + }), + ), + ); + + // BRANCHES // + console.log('Updating Branches'); + const branches = [ + { code: 'TC', name: 'Tronc commun', isMaster: false }, + { code: 'RT', name: 'Réseaux et télécommunications', isMaster: false }, + { code: 'GM', name: 'Génie mécanique', isMaster: false }, + { code: 'GM_APPR', name: 'Génie mécanique - Apprentissage', isMaster: false }, + { code: 'A2I', name: 'Automatique et informatique industrielle', isMaster: false }, + { code: 'MTE', name: 'Matériaux: Technologie et Economie', isMaster: false }, + { code: 'ISI', name: "Informatique et Systèmes d'Information", isMaster: false }, + { code: 'SN_APPR', name: 'Systèmes Numériques - Apprentissage', isMaster: false }, + { code: 'MM', name: 'Matériaux et Mécanique', isMaster: false }, + { code: 'GI', name: 'Génie Industriel', isMaster: false }, + { code: 'GI_APPR', name: 'Génie Industriel - Apprentissage', isMaster: false }, + { code: 'RE', name: 'Risques et Environnement', isMaster: true }, + { code: 'PAIP', name: 'Physique Appliquée et Ingénierie Physique', isMaster: true }, + { code: 'ISC', name: 'Ingénierie des Systèmes Complexes', isMaster: true }, + { code: 'IC', name: 'Ingénierie de Conception', isMaster: true }, + ]; + await Promise.all( + branches.map((branch) => + prisma.uTTBranch.upsert({ + where: { + code: branch.code, + }, + update: branch, + create: { + ...branch, + descriptionTranslation: { + create: {}, + }, + }, + }), + ), + ); + + // BRANCH OPTIONS // + console.log('Updating branch options'); + const branch_options = [ + { code: 'TC', name: 'Tronc commun', branch: 'TC' }, + { code: 'GM', name: 'Tronc commun de Génie Mécanique', branch: 'GM' }, + { code: 'A2I', name: "Tronc commun d'Automatique et informatique industrielle", branch: 'A2I' }, + { code: 'MTE', name: 'Tronc commun de Matériaux: Technologie et Economie', branch: 'MTE' }, + { code: 'GM_APPR', name: 'Tronc commun de Génie mécanique - Apprentissage', branch: 'GM_APPR' }, + { code: 'ISI', name: "Tronc commun d'Informatique et Systèmes d'Information", branch: 'ISI' }, + { code: 'MM', name: 'Tronc commun de Matériaux et Mécanique', branch: 'MM' }, + { code: 'GI_APPR', name: 'Tronc commun de Génie Industriel - Apprentissage', branch: 'GI_APPR' }, + { code: 'SN_APPR', name: 'Tronc commun de Systèmes Numériques - Apprentissage', branch: 'SN_APPR' }, + { code: 'RT', name: 'Tronc commun de Réseaux et télécommunications', branch: 'RT' }, + { code: 'GI', name: 'Tronc commun de Génie Industriel', branch: 'GI' }, + { code: 'MDPI_APPR', name: 'Management Digital des Produits et Infrastructures - Apprentissage', branch: 'GM' }, + { code: 'LIP_APPR', name: 'Logistique interne et production - Apprentissage', branch: 'GI' }, + { code: 'LET_APPR', name: 'Logistique externe et transport - Apprentissage', branch: 'GI' }, + { code: 'TQM', name: 'Transformation et qualité des matériaux', branch: 'MTE' }, + { code: 'TCMC', name: 'Technologie et commerce des matériaux et des composants', branch: 'MTE' }, + { code: 'TEI', name: 'Technologie embarquée et interopérabilité', branch: 'A2I' }, + { code: 'SPI', name: 'Systèmes de production intelligents', branch: 'A2I' }, + { + code: 'CEISME', + name: "Conception et industrialisation des systèmes mécaniques, en lien avec l'environnement", + branch: 'GM', + }, + { code: 'EME', name: 'Énergie, matériaux et environnement', branch: 'MTE' }, + { code: 'SSC', name: 'Sécurité des systèmes et des communications', branch: 'RT' }, + { code: 'IPL', name: 'Innovation par le logiciel', branch: 'ISI' }, + { code: 'ATN', name: 'Accompagnement de la Transformation Numérique', branch: 'ISI' }, + { code: 'VDC', name: 'Valorisation des données et des connaissances', branch: 'ISI' }, + { code: 'TMOC', name: 'Technologies mobiles et objets connectés', branch: 'RT' }, + { code: 'MDPI', name: 'Management Digital des Produits et infrastructures', branch: 'GM' }, + { code: 'SNM', name: 'Simulation numérique en mécanique', branch: 'GM' }, + { code: 'CSR', name: 'Convergence service réseaux', branch: 'RT' }, + { code: 'RAMS', name: 'Fiabilité, Maintenance, Disponibilité et Sûreté', branch: 'GI' }, + { code: 'RAMS_APPR', name: 'Fiabilité, Maintenance, Disponibilité et Sûreté - Apprentissage', branch: 'GI' }, + { code: 'SN', name: 'Tronc commun de Systèmes Numériques', branch: 'SN_APPR' }, + { code: 'LIP', name: 'Logistique interne et production', branch: 'GI' }, + { code: 'LET', name: 'Logistique externe et transport', branch: 'GI' }, + { code: 'RE', name: 'Mention Risques et Environnement', branch: 'RE' }, + { code: 'PAIP', name: 'Mention Physique Appliquée et Ingénierie Physique', branch: 'PAIP' }, + { code: 'ISC', name: 'Mention Ingénierie des Systèmes Complexes', branch: 'ISC' }, + { code: 'IC', name: 'Mention Ingénierie de Conception', branch: 'IC' }, + { code: 'IMEDD', name: "Ingénierie et Management de l'Environnement et du Développement Durable", branch: 'RE' }, + { code: 'SSI', name: "Sécurité des Systèmes d'Information", branch: 'ISC' }, + { code: 'NPHOT', name: 'Nano-optics and Nanophotonics', branch: 'PAIP' }, + { code: 'MPSMP', name: 'Mécanique et Performance en Service de Matériaux et Produits', branch: 'IC' }, + { code: 'OSS', name: 'Optimisation et Sûreté des Systèmes', branch: 'ISC' }, + { code: 'IMSGA', name: 'Ingénierie et Management en Sécurité Globale Appliquée', branch: 'RE' }, + ]; + await Promise.all( + branch_options.map((option) => + prisma.uTTBranchOption.upsert({ + where: { + code: option.code, + }, + update: { + branchCode: option.branch, + name: option.name, + }, + create: { + code: option.code, + name: option.name, + branch: { + connect: { + code: option.branch, + }, + }, + descriptionTranslation: { + create: {}, + }, + }, + }), + ), + ); +} + +main(); diff --git a/scripts/seed/ue.ts b/scripts/seed/ue.ts new file mode 100644 index 0000000..45c308e --- /dev/null +++ b/scripts/seed/ue.ts @@ -0,0 +1,343 @@ +import { createReadStream } from 'fs'; +import { createInterface } from 'readline/promises'; +import { parse } from '@fast-csv/parse'; +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +type UEOF = { + entry_nb: string; + siep_id: number; + ueof_code: string; + code: string; + name: string; + objectives: string; + program: string; + lang: string; + cm_hours: number; + td_hours: number; + tp_hours: number; + the_hours: number; + has_project: boolean; + internship_hours: number; + credit_count: number; + engineer_credit_type?: string; + master_credit_type?: string; + semesters: string[]; + minors: string[]; + requirements: string[]; + engineer_branch: string[]; + engineer_branch_option: string[]; + master_branch: string[]; + master_branch_option: string[]; +}; +type DataHeader = keyof UEOF; + +async function findPadding(document: string) { + return new Promise((resolve, reject) => { + const readable = createReadStream(document); + const reader = createInterface({ input: readable }); + let count = 0; + reader + .on('line', (line) => { + count++; + if (!line) { + resolve(count); + readable.destroy(); + } + }) + .on('close', () => reject()); + }); +} + +async function parseDocument(document: string) { + return new Promise(async (resolve, reject) => { + const ueofs: UEOF[] = []; + const padding = await findPadding(document); + createReadStream(document) + .pipe( + parse({ + delimiter: ';', + skipLines: padding, + headers: [ + 'entry_nb', + 'siep_id', + 'ueof_code', + 'code', + 'name', + 'objectives', + 'program', + 'cm_hours', + 'td_hours', + 'tp_hours', + 'the_hours', + 'internship_hours', + 'credit_count', + 'lang', + 'minors', + 'semesters', + 'has_project', + 'engineer_credit_type', + 'master_credit_type', + 'requirements', + 'engineer_branch', + 'engineer_branch_option', + 'master_branch_option', + 'master_branch', + ] satisfies DataHeader[], + renameHeaders: true, + }), + ) + .on('error', (error) => { + console.error('\x1b[41;30mAn error occurred while parsing UE datasource\x1b[0m'); + console.error(error); + reject(); + }) + .on('data', (ue) => + ueofs.push({ + ...ue, + siep_id: Number(ue.siep_id), + cm_hours: Number(ue.cm_hours) || 0, + td_hours: Number(ue.td_hours) || 0, + tp_hours: Number(ue.tp_hours) || 0, + the_hours: Number(ue.the_hours) || 0, + has_project: ue.has_project === 'OUI', + internship_hours: Number(ue.internship_hours) || 0, + credit_count: Number(ue.credit_count) || 0, + requirements: ue.requirements ? [ue.requirements as unknown as string] : [], + semesters: ue.semesters ? (ue.semesters as unknown as string).split(/\s\/\s/g) : [], + minors: ue.minors ? (ue.minors as unknown as string).split(/\s\/\s/g) : [], + engineer_branch: ue.engineer_branch ? (ue.engineer_branch as unknown as string).split(/\s\/\s/g) : [], + engineer_branch_option: ue.engineer_branch_option + ? (ue.engineer_branch_option as unknown as string)?.split(/\s\/\s/g) + : [], + master_branch: ue.master_branch ? (ue.master_branch as unknown as string).split(/\s\/\s/g) : [], + master_branch_option: ue.master_branch_option + ? (ue.master_branch_option as unknown as string).split(/\s\/\s/g) + : [], + }), + ) + .on('end', () => + resolve( + // A single UEOF can appear multiple times in the CSV with a different requirement + // We group the UEOFs by their code and merge the requirements + Object.values(ueofs.groupyBy((ueof) => ueof.ueof_code)).map((duplicates) => ({ + ...duplicates[0], + requirements: duplicates.flatMap((ueof) => ueof.requirements), + })), + ), + ); + }); +} + +async function main() { + const importYear = new Date().getFullYear(); // Can be changed to the year of the import if done with web interface + + console.info('\x1b[42;30mFetching UE list\x1b[0m'); + const ues = await parseDocument('scripts/seed/dfp_data.csv'); + await prisma.ueof.updateMany({ + data: { available: false }, + }); + + console.info('\x1b[42;30mUpdating UEs\x1b[0m'); + const branches = await prisma.uTTBranch.findMany({ + select: { + isMaster: true, + code: true, + }, + }); + for (const ue of ues) { + // Generating ue credits (includes branch and branch options) + const credits: { category: string; credits: number; branchOptions: string[] }[] = []; + if (ue.engineer_credit_type) + credits.push({ + category: ue.engineer_credit_type, + credits: ue.credit_count, + branchOptions: ue.engineer_branch_option.length + ? ue.engineer_branch_option + : ue.engineer_branch.length + ? ue.engineer_branch + : branches.filter((branch) => !branch.isMaster).map((branch) => branch.code), + }); + if (ue.master_credit_type) + credits.push({ + category: ue.master_credit_type, + credits: ue.credit_count, + branchOptions: ue.master_branch_option.length + ? ue.master_branch_option + : ue.master_branch.length + ? ue.master_branch + : branches.filter((branch) => branch.isMaster).map((branch) => branch.code), + }); + if (ue.code === 'PE00') + credits.push( + ...['CS', 'TM', 'EC', 'ME', 'HT', 'AC'].map((code) => ({ + category: code, + credits: ue.credit_count, + branchOptions: branches.filter((branch) => !branch.isMaster).map((branch) => branch.code), + })), + ); + // Update database ue data + await prisma.ueof.upsert({ + where: { + code: ue.ueof_code, + }, + create: { + code: ue.ueof_code, + siepId: ue.siep_id, + ue: { + connectOrCreate: { + where: { code: ue.code }, + create: { + code: ue.code, + }, + }, + }, + name: { + create: { + fr: ue.name, + }, + }, + available: true, + info: { + create: { + language: ue.lang, + minors: ue.minors.join(), + objectives: { + create: { + fr: ue.objectives, + }, + }, + program: { + create: { + fr: ue.program, + }, + }, + }, + }, + workTime: { + create: { + cm: ue.cm_hours, + td: ue.td_hours, + tp: ue.tp_hours, + the: ue.the_hours, + internship: ue.internship_hours, + project: ue.has_project, + }, + }, + credits: { + create: credits.map((credit) => ({ + credits: credit.credits, + category: { + connect: { + code: credit.category, + }, + }, + branchOptions: { + connect: credit.branchOptions.map((code) => ({ + code: code, + })), + }, + })), + }, + openSemester: { + connect: ue.semesters.map((code) => ({ + code: `${code}${(importYear + Number(code === 'P')) % 100}`, + })), + }, + }, + update: { + siepId: ue.siep_id, + name: { + update: { + fr: ue.name, + }, + }, + available: true, + info: { + update: { + language: ue.lang, + minors: ue.minors.join(), + objectives: { + update: { + fr: ue.objectives, + }, + }, + program: { + update: { + fr: ue.program, + }, + }, + }, + }, + workTime: { + update: { + cm: ue.cm_hours, + td: ue.td_hours, + tp: ue.tp_hours, + the: ue.the_hours, + internship: ue.internship_hours, + project: ue.has_project, + }, + }, + credits: { + deleteMany: {}, + create: credits.map((credit) => ({ + credits: credit.credits, + category: { + connect: { + code: credit.category, + }, + }, + branchOptions: { + connect: credit.branchOptions.map((code) => ({ + code: code, + })), + }, + })), + }, + openSemester: { + connect: ue.semesters.map((code) => ({ + code: `${code}${(importYear + Number(code === 'P')) % 100}`, + })), + }, + }, + }); + } + + const aliases = await prisma.ueAlias.findMany(); + + console.info('\x1b[42;30mImporting UE requirements...\x1b[0m'); + + try { + await Promise.all( + ues.map((ueof) => + prisma.ueof.update({ + where: { + code: ueof.ueof_code, + }, + data: { + requirements: { + connect: ueof.requirements + .map((code) => { + const result = aliases.find((alias) => alias.code === code); + return result ? result.standsFor : code; + }) + .filter((code) => code) + .map((code) => ({ + code: code, + })), + }, + }, + }), + ), + ); + console.info('\x1b[42;30m✅ Import complete\x1b[0m'); + } catch (error) { + console.error( + '\x1b[41;30mAn error occurred while importing UE requirements. Try `$ pnpm seed:ue:aliases` first.\x1b[0m', + ); + } +} + +main(); diff --git a/src/array.ts b/src/array.ts index a6948ed..78780bd 100644 --- a/src/array.ts +++ b/src/array.ts @@ -1,5 +1,9 @@ declare global { interface Array { + /** + * Groups the current array by a key, using a mapper function. + */ + groupyBy(keyMapper: (entity: T) => K): { [key in K]: T[] }; /** * Sorts the current array and returns it. * Array is sorted based on a mapper function, that returns in order the values by which to sort the array. @@ -20,9 +24,23 @@ declare global { * The length of the array should be fixed, not dependent on the value to map. */ mappedSort(mapper: (e: T) => any[] | any): this; + /** Retrieves all unique values of this array, skipping all duplicates. Does not alter original array */ + readonly uniqueValues: this; } } +Array.prototype.groupyBy = function ( + this: Array, + keyMapper: (entity: T) => K, +) { + return this.reduce((acc, entity) => { + const key = keyMapper(entity); + if (!acc[key]) acc[key] = []; + acc[key].push(entity); + return acc; + }, {} as { [key in K]: T[] }); +}; + Array.prototype.mappedSort = function (this: Array, mapper: (e: T) => any[] | any) { return this.sort((a, b) => { const aMapped = mapper(a); @@ -41,4 +59,10 @@ Array.prototype.mappedSort = function (this: Array, mapper: (e: T) => any[ }); }; +Object.defineProperty(Array.prototype, 'uniqueValues', { + get: function (this: Array) { + return this.filter((value, index) => this.indexOf(value) === index); + }, +}); + export {}; diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 04b1667..9376b94 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -51,7 +51,7 @@ export class AuthService { dto.studentId = Number(ldapUser.supannEtuId); type = UserType.STUDENT; branch.push(...(Array.isArray(ldapUser.niveau) ? ldapUser.niveau : [ldapUser.niveau])); - ues.push(...(Array.isArray(ldapUser.uv) ? ldapUser.uv : [ldapUser.uv])); + ues.push(...(Array.isArray(ldapUser.uv) ? ldapUser.uv : [ldapUser.uv])); // TODO : check what is done by the admin : are they UEOF or UE codes ? branchOption.push(...(Array.isArray(ldapUser.filiere) ? ldapUser.filiere : [ldapUser.filiere])); [formation] = Array.isArray(ldapUser.formation) ? ldapUser.formation : [ldapUser.formation]; // TODO: this is wrong, students can have multiple formations ! } else if (ldapUser.gidNumber === LdapAccountGroup.EMPLOYEES) { @@ -113,10 +113,8 @@ export class AuthService { UesSubscriptions: currentSemester ? { createMany: { - data: ( - await this.ueService.getIdFromCode(ues) - ).map((id) => ({ - ueId: id, + data: ues.map((id) => ({ + ueofId: id, semesterId: currentSemester.code, })), }, diff --git a/src/exceptions.ts b/src/exceptions.ts index b5a5afa..cad5d1b 100644 --- a/src/exceptions.ts +++ b/src/exceptions.ts @@ -23,16 +23,17 @@ export const enum ERROR_CODE { PARAM_NOT_ENUM = 2007, PARAM_NOT_DATE = 2008, PARAM_NOT_UUID = 2009, - PARAM_TOO_LONG = 20010, - PARAM_TOO_SHORT = 2011, - PARAM_SIZE_TOO_SMALL = 2012, - PARAM_SIZE_TOO_BIG = 2013, - PARAM_IS_EMPTY = 2014, - PARAM_NOT_POSITIVE = 2015, - PARAM_TOO_LOW = 2016, - PARAM_TOO_HIGH = 2017, - PARAM_NOT_INT = 2018, - NO_FILE_PROVIDED = 2019, + PARAM_INVALID_SIZE = 2010, + PARAM_TOO_LONG = 2011, + PARAM_TOO_SHORT = 2012, + PARAM_SIZE_TOO_SMALL = 2013, + PARAM_SIZE_TOO_BIG = 2014, + PARAM_IS_EMPTY = 2015, + PARAM_NOT_POSITIVE = 2016, + PARAM_TOO_LOW = 2017, + PARAM_TOO_HIGH = 2018, + PARAM_NOT_INT = 2019, + NO_FILE_PROVIDED = 2020, PARAM_DOES_NOT_MATCH_REGEX = 2102, NO_FIELD_PROVIDED = 2201, WIDGET_OVERLAPPING = 2301, @@ -52,9 +53,10 @@ export const enum ERROR_CODE { NOT_REPLY_AUTHOR = 4223, IS_COMMENT_AUTHOR = 4224, GROUP_NOT_PART_OF_ENTRY = 4225, - NOT_ALREADY_RATED_UE = 4226, + NOT_ALREADY_RATED_UEOF = 4226, NOT_DONE_UE_IN_SEMESTER = 4227, NOT_ANNAL_SENDER = 4228, + NOT_ALREADY_DONE_UEOF = 4229, NO_SUCH_UE = 4401, NO_SUCH_COMMENT = 4402, NO_SUCH_REPLY = 4403, @@ -65,6 +67,7 @@ export const enum ERROR_CODE { NO_SUCH_ANNAL = 4408, NO_SUCH_ANNAL_TYPE = 4409, NO_SUCH_ASSO = 4410, + NO_SUCH_UEOF = 4411, ANNAL_ALREADY_UPLOADED = 4901, CREDENTIALS_ALREADY_TAKEN = 5001, } @@ -115,6 +118,10 @@ export const ErrorData = Object.freeze({ message: 'The following parameters must be a valid UUID: %', httpCode: HttpStatus.BAD_REQUEST, }, + [ERROR_CODE.PARAM_INVALID_SIZE]: { + message: 'The following parameters do not match required size: %', + httpCode: HttpStatus.BAD_REQUEST, + }, [ERROR_CODE.PARAM_TOO_LONG]: { message: 'The following parameters are too long: %', httpCode: HttpStatus.BAD_REQUEST, @@ -231,7 +238,7 @@ export const ErrorData = Object.freeze({ message: 'The group % is not part of the timetable entry %', httpCode: HttpStatus.FORBIDDEN, }, - [ERROR_CODE.NOT_ALREADY_RATED_UE]: { + [ERROR_CODE.NOT_ALREADY_RATED_UEOF]: { message: 'You must have rated the UE % (on criterion %) before deleting your rating', httpCode: HttpStatus.FORBIDDEN, }, @@ -243,6 +250,10 @@ export const ErrorData = Object.freeze({ message: 'You are not the sender of this annal', httpCode: HttpStatus.FORBIDDEN, }, + [ERROR_CODE.NOT_ALREADY_DONE_UEOF]: { + message: 'You must have done this UEOF before to perform this action', + httpCode: HttpStatus.FORBIDDEN, + }, [ERROR_CODE.NO_SUCH_UE]: { message: 'The UE % does not exist', httpCode: HttpStatus.NOT_FOUND, @@ -283,6 +294,10 @@ export const ErrorData = Object.freeze({ message: 'The asso % does no exist', httpCode: HttpStatus.NOT_FOUND, }, + [ERROR_CODE.NO_SUCH_UEOF]: { + message: 'UEOF % does no exist', + httpCode: HttpStatus.NOT_FOUND, + }, [ERROR_CODE.ANNAL_ALREADY_UPLOADED]: { message: 'A file has alreay been uploaded for this annal', httpCode: HttpStatus.CONFLICT, diff --git a/src/ldap/ldap.module.ts b/src/ldap/ldap.module.ts index a5ba249..a27b2c7 100644 --- a/src/ldap/ldap.module.ts +++ b/src/ldap/ldap.module.ts @@ -1,7 +1,7 @@ import { Injectable, Module } from '@nestjs/common'; import { Client as LdapClient } from 'ldapts'; import { ConfigModule } from '../config/config.module'; -import { LdapAccountGroup, LdapUser } from './ldap.interface'; +import { LdapUser } from './ldap.interface'; @Module({ exports: [LdapModule], diff --git a/src/prisma/types.ts b/src/prisma/types.ts index 6021916..6f2ec33 100644 --- a/src/prisma/types.ts +++ b/src/prisma/types.ts @@ -13,7 +13,7 @@ export { Ue as RawUe, UeCredit as RawUeCredit, UeCreditCategory as RawCreditCategory, - UeInfo as RawUeInfo, + UeofInfo as RawUeofInfo, UeWorkTime as RawUeWorkTime, UeStarVote as RawUeStarVote, UeStarCriterion as RawUeStarCriterion, diff --git a/src/semester/semester.service.ts b/src/semester/semester.service.ts index 13396cf..47d99c3 100644 --- a/src/semester/semester.service.ts +++ b/src/semester/semester.service.ts @@ -55,6 +55,11 @@ export class SemesterService { start: { lte: new Date(), }, + code: { + not: { + contains: 'U', + }, + }, }, }); } diff --git a/src/types.d.ts b/src/types.d.ts index aaa6df3..f6dce5f 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -19,3 +19,6 @@ declare type SetPartial = Omit & Partial> declare type RecursivelySetPartial = K extends `${infer K1}.${infer K2}` ? Omit & RecursivelySetPartial : SetPartial; + +/** Retrieves the type of items of an {@link Array} */ +declare type ItemType = T extends Array ? U : T; diff --git a/src/ue/annals/annals.controller.ts b/src/ue/annals/annals.controller.ts index 5e0c16f..3283078 100644 --- a/src/ue/annals/annals.controller.ts +++ b/src/ue/annals/annals.controller.ts @@ -21,29 +21,32 @@ export class AnnalsController { @RequireUserType('STUDENT', 'FORMER_STUDENT') async getUeAnnalList(@Query() { ueCode }: GetFromUeCodeDto, @GetUser() user: User) { if (!(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); - return this.annalsService.getUEAnnalsList(user, ueCode, user.permissions.includes('annalModerator')); + return this.annalsService.getUeAnnalsList(user, ueCode, user.permissions.includes('annalModerator')); } @Post() @RequireUserType('STUDENT') - async createUeAnnal(@Body() { ueCode, semester, typeId }: CreateAnnal, @GetUser() user: User) { - if (!(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); + async createUeAnnal(@Body() { ueCode, semester, typeId, ueof }: CreateAnnal, @GetUser() user: User) { + if (ueof && !user.permissions.includes('annalUploader')) + throw new AppException(ERROR_CODE.FORBIDDEN_NOT_ENOUGH_PERMISSIONS, 'annalUploader'); + if (!ueof && !(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); + if (ueof && !(await this.ueService.doesUeofExist(ueof))) throw new AppException(ERROR_CODE.NO_SUCH_UEOF, ueof); if (!(await this.annalsService.doesAnnalTypeExist(typeId))) throw new AppException(ERROR_CODE.NO_SUCH_ANNAL_TYPE); if ( - !(await this.ueService.hasDoneThisUeInSemester(user.id, ueCode, semester)) && + !(await this.ueService.hasUserAttended(ueCode, user.id, semester)) && !user.permissions.includes('annalUploader') ) throw new AppException(ERROR_CODE.NOT_DONE_UE_IN_SEMESTER, ueCode, semester); - return this.annalsService.createAnnalFile(user, { ueCode, semester, typeId }); + return await this.annalsService.createAnnalFile(user, { ueCode, semester, typeId, ueof }); } @Get('metadata') @RequireUserType('STUDENT', 'FORMER_STUDENT') async getUeAnnalMetadata(@Query() { ueCode }: GetFromUeCodeDto, @GetUser() user: User) { if (!(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); - if (!(await this.ueService.hasAlreadyDoneThisUe(user.id, ueCode)) && !user.permissions.includes('annalUploader')) + if (!(await this.ueService.hasUserAttended(ueCode, user.id)) && !user.permissions.includes('annalUploader')) throw new AppException(ERROR_CODE.NOT_ALREADY_DONE_UE); - return this.annalsService.getUEAnnalMetadata(user, ueCode, user.permissions.includes('annalUploader')); + return this.annalsService.getUeAnnalMetadata(user, ueCode, user.permissions.includes('annalUploader')); } @Put(':annalId') @@ -59,10 +62,10 @@ export class AnnalsController { @Query() { rotate }: UploadAnnalDto, @GetUser() user: User, ) { - if (!(await this.annalsService.isUEAnnalSender(user.id, annalId))) + if (!(await this.annalsService.isUeAnnalSender(user.id, annalId))) throw new AppException(ERROR_CODE.NOT_ANNAL_SENDER); if ( - (await this.annalsService.getUEAnnal(annalId, user.id, user.permissions.includes('annalModerator'))).status !== + (await this.annalsService.getUeAnnal(annalId, user.id, user.permissions.includes('annalModerator'))).status !== CommentStatus.PROCESSING ) throw new AppException(ERROR_CODE.ANNAL_ALREADY_UPLOADED); @@ -78,7 +81,7 @@ export class AnnalsController { ) { if (!(await this.annalsService.isAnnalAccessible(user.id, annalId, user.permissions.includes('annalModerator')))) throw new AppException(ERROR_CODE.NO_SUCH_ANNAL, annalId); - const annalFile = await this.annalsService.getUEAnnalFile( + const annalFile = await this.annalsService.getUeAnnalFile( annalId, user.id, user.permissions.includes('annalModerator'), @@ -87,7 +90,7 @@ export class AnnalsController { response.setHeader('Content-Type', 'application/pdf'); response.setHeader( 'Content-Disposition', - `attachment; filename=${annalFile.metadata.type.name} ${annalFile.metadata.ue.code} - ${annalFile.metadata.semesterId}`, + `attachment; filename=${annalFile.metadata.type.name} ${annalFile.metadata.ueof.code} - ${annalFile.metadata.semesterId}`, ); annalFile.stream.pipe(response); } @@ -97,7 +100,7 @@ export class AnnalsController { async updateUeAnnal(@UUIDParam('annalId') annalId: string, @Body() body: UpdateAnnalDto, @GetUser() user: User) { if (!(await this.annalsService.isAnnalAccessible(user.id, annalId, user.permissions.includes('annalModerator')))) throw new AppException(ERROR_CODE.NO_SUCH_ANNAL, annalId); - if (!(await this.annalsService.isUEAnnalSender(user.id, annalId)) && !user.permissions.includes('annalModerator')) + if (!(await this.annalsService.isUeAnnalSender(user.id, annalId)) && !user.permissions.includes('annalModerator')) throw new AppException(ERROR_CODE.NOT_ANNAL_SENDER); return this.annalsService.updateAnnalMetadata(annalId, body); } @@ -107,7 +110,7 @@ export class AnnalsController { async deleteUeAnnal(@UUIDParam('annalId') annalId: string, @GetUser() user: User) { if (!(await this.annalsService.isAnnalAccessible(user.id, annalId, user.permissions.includes('annalModerator')))) throw new AppException(ERROR_CODE.NO_SUCH_ANNAL, annalId); - if (!(await this.annalsService.isUEAnnalSender(user.id, annalId)) && !user.permissions.includes('annalModerator')) + if (!(await this.annalsService.isUeAnnalSender(user.id, annalId)) && !user.permissions.includes('annalModerator')) throw new AppException(ERROR_CODE.NOT_ANNAL_SENDER); return this.annalsService.deleteAnnal(annalId); } diff --git a/src/ue/annals/annals.service.ts b/src/ue/annals/annals.service.ts index 1427d90..91f002d 100644 --- a/src/ue/annals/annals.service.ts +++ b/src/ue/annals/annals.service.ts @@ -9,15 +9,20 @@ import { CreateAnnal } from './dto/create-annal.dto'; import { UpdateAnnalDto } from './dto/update-annal.dto'; import { ConfigModule } from '../../config/config.module'; import { User } from '../../users/interfaces/user.interface'; +import { Semester } from '@prisma/client'; @Injectable() export class AnnalsService { constructor(readonly prisma: PrismaService, readonly config: ConfigModule) {} - async getUEAnnalMetadata(user: User, ueCode: string, isModerator: boolean) { - const ue = await this.prisma.ue.findUnique({ + async getUeAnnalMetadata(user: User, ueCode: string, isModerator: boolean) { + const ueof = await this.prisma.ueof.findMany({ where: { - code: ueCode, + ueId: ueCode, + available: true, + }, + include: { + openSemester: true, }, }); const semesters = !isModerator @@ -25,11 +30,15 @@ export class AnnalsService { await this.prisma.userUeSubscription.findMany({ where: { userId: user.id, - ueId: ue.id, + ueof: { + ueId: ueCode, + }, }, }) ).map((subscription) => subscription.semesterId) - : ue.openSemester.map((semester) => semester.code); + : [...ueof.reduce((prev, nxt) => new Set([...prev, ...nxt.openSemester]), new Set())].map( + (semester) => semester.code, + ); const annalType = await this.prisma.ueAnnalType.findMany(); return { types: annalType, @@ -48,6 +57,15 @@ export class AnnalsService { } async createAnnalFile(user: User, params: CreateAnnal) { + const subscription = await this.prisma.userUeSubscription.findFirst({ + where: { + semesterId: params.semester, + userId: user.id, + ueof: { + ueId: params.ueCode, + }, + }, + }); // Create upload/file entry return this.prisma.ueAnnal.create({ data: { @@ -66,9 +84,9 @@ export class AnnalsService { id: user.id, }, }, - ue: { + ueof: { connect: { - code: params.ueCode, + code: subscription.ueofId ?? params.ueof, }, }, }, @@ -128,7 +146,7 @@ export class AnnalsService { size, compress: true, info: { - Title: `${fileEntry.type.name} ${fileEntry.ue.code} - ${fileEntry.semesterId}`, + Title: `${fileEntry.type.name} ${fileEntry.ueof.code} - ${fileEntry.semesterId}`, Creator: 'EtuUTT', Producer: 'EtuUTT', }, @@ -160,12 +178,14 @@ export class AnnalsService { return fileEntry; } - async getUEAnnalsList(user: User, ueCode: string, includeAll: boolean) { + async getUeAnnalsList(user: User, ueCode: string, includeAll: boolean) { return ( await this.prisma.ueAnnal.findMany({ where: { - ue: { - code: ueCode, + ueof: { + ue: { + code: ueCode, + }, }, deletedAt: includeAll ? undefined : null, ...(includeAll @@ -233,7 +253,7 @@ export class AnnalsService { ); } - async getUEAnnal(annalId: string, userId: string, includeAll: boolean) { + async getUeAnnal(annalId: string, userId: string, includeAll: boolean) { return this.prisma.ueAnnal.findUnique({ where: { id: annalId, @@ -264,7 +284,7 @@ export class AnnalsService { }); } - async getUEAnnalFile(annalId: string, userId: string, includeAll: boolean) { + async getUeAnnalFile(annalId: string, userId: string, includeAll: boolean) { const metadata = await this.prisma.ueAnnal.findUnique({ where: { id: annalId, @@ -300,7 +320,7 @@ export class AnnalsService { }; } - async isUEAnnalSender(userId: string, annalId: string) { + async isUeAnnalSender(userId: string, annalId: string) { return ( (await this.prisma.ueAnnal.count({ where: { diff --git a/src/ue/annals/dto/create-annal.dto.ts b/src/ue/annals/dto/create-annal.dto.ts index 2b0c04d..a9c2987 100644 --- a/src/ue/annals/dto/create-annal.dto.ts +++ b/src/ue/annals/dto/create-annal.dto.ts @@ -1,4 +1,14 @@ -import { IsAlphanumeric, IsNotEmpty, IsString, IsUUID, Length, MaxLength, MinLength } from 'class-validator'; +import { + IsAlphanumeric, + IsNotEmpty, + IsOptional, + IsString, + IsUUID, + Length, + MaxLength, + MinLength, + ValidateIf, +} from 'class-validator'; export class CreateAnnal { @IsString() @@ -12,9 +22,17 @@ export class CreateAnnal { typeId: string; @IsString() + @ValidateIf((obj: CreateAnnal) => !!obj.ueCode || !!obj.ueof) @IsNotEmpty() @IsAlphanumeric() @MinLength(3) @MaxLength(5) ueCode: string; + + @IsOptional() + @IsString() + @IsNotEmpty() + @MaxLength(20) + @MinLength(12) + ueof?: string; } diff --git a/src/ue/annals/interfaces/annal.interface.ts b/src/ue/annals/interfaces/annal.interface.ts index 3d42619..0ef61ee 100644 --- a/src/ue/annals/interfaces/annal.interface.ts +++ b/src/ue/annals/interfaces/annal.interface.ts @@ -25,7 +25,7 @@ const UE_ANNAL_SELECT_FILTER = { }, }, validatedAt: true, - ue: { select: { code: true } }, + ueof: { select: { code: true, info: { select: { language: true } }, ue: { select: { code: true } } } }, }, } satisfies Prisma.UeAnnalFindManyArgs; diff --git a/src/ue/comments/comments.controller.ts b/src/ue/comments/comments.controller.ts index 218dd49..db098b6 100644 --- a/src/ue/comments/comments.controller.ts +++ b/src/ue/comments/comments.controller.ts @@ -16,16 +16,17 @@ export class CommentsController { @Get() @RequireUserType('STUDENT', 'FORMER_STUDENT') - async getUEComments(@GetUser() user: User, @Query() dto: GetUeCommentsDto) { + async getUeComments(@GetUser() user: User, @Query() dto: GetUeCommentsDto) { if (!(await this.ueService.doesUeExist(dto.ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, dto.ueCode); return this.commentsService.getComments(user.id, dto, user.permissions.includes('commentModerator')); } @Post() @RequireUserType('STUDENT') - async PostUEComment(@GetUser() user: User, @Body() body: UeCommentPostDto) { + async PostUeComment(@GetUser() user: User, @Body() body: UeCommentPostDto) { + // FIXME : a user can only post one comment per ue (among all ueofs) if (!(await this.ueService.doesUeExist(body.ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, body.ueCode); - if (!(await this.ueService.hasAlreadyDoneThisUe(user.id, body.ueCode))) + if (!(await this.ueService.hasUserAttended(body.ueCode, user.id))) throw new AppException(ERROR_CODE.NOT_ALREADY_DONE_UE); if (await this.commentsService.hasAlreadyPostedAComment(user.id, body.ueCode)) throw new AppException(ERROR_CODE.FORBIDDEN_ALREADY_COMMENTED); @@ -34,7 +35,7 @@ export class CommentsController { @Get(':commentId') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async getUECommentFromId(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { + async getUeCommentFromId(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { const comment = await this.commentsService.getCommentFromId( commentId, user.id, @@ -46,7 +47,7 @@ export class CommentsController { @Patch(':commentId') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async EditUEComment( + async editUeComment( @UUIDParam('commentId') commentId: string, @GetUser() user: User, @Body() body: UeCommentUpdateDto, @@ -79,7 +80,7 @@ export class CommentsController { @Delete(':commentId') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async DiscardUEComment(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { + async discardUeComment(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { if ( !(await this.commentsService.doesCommentExist(commentId, user.id, user.permissions.includes('commentModerator'))) ) @@ -99,7 +100,7 @@ export class CommentsController { @Post(':commentId/upvote') @RequireUserType('STUDENT') @HttpCode(HttpStatus.OK) - async UpvoteUEComment(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { + async UpvoteUeComment(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { if ( !(await this.commentsService.doesCommentExist( commentId, @@ -122,7 +123,7 @@ export class CommentsController { @Delete(':commentId/upvote') @RequireUserType('STUDENT', 'FORMER_STUDENT') @HttpCode(HttpStatus.OK) - async UnUpvoteUEComment(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { + async UnUpvoteUeComment(@UUIDParam('commentId') commentId: string, @GetUser() user: User) { if ( !(await this.commentsService.doesCommentExist( commentId, @@ -144,7 +145,7 @@ export class CommentsController { @Post(':commentId/reply') @RequireUserType('STUDENT') - async CreateReplyComment( + async createReplyComment( @GetUser() user: User, @UUIDParam('commentId') commentId: string, @Body() body: CommentReplyDto, @@ -163,7 +164,7 @@ export class CommentsController { @Patch('reply/:replyId') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async EditReplyComment(@GetUser() user: User, @UUIDParam('replyId') replyId: string, @Body() body: CommentReplyDto) { + async editReplyComment(@GetUser() user: User, @UUIDParam('replyId') replyId: string, @Body() body: CommentReplyDto) { if (!(await this.commentsService.doesReplyExist(replyId))) throw new AppException(ERROR_CODE.NO_SUCH_REPLY); if ( (await this.commentsService.isUserCommentReplyAuthor(user.id, replyId)) || @@ -175,7 +176,7 @@ export class CommentsController { @Delete('reply/:replyId') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async DeleteReplyComment(@GetUser() user: User, @UUIDParam('replyId') replyId: string) { + async deleteReplyComment(@GetUser() user: User, @UUIDParam('replyId') replyId: string) { if (!(await this.commentsService.doesReplyExist(replyId))) throw new AppException(ERROR_CODE.NO_SUCH_REPLY); if ( (await this.commentsService.isUserCommentReplyAuthor(user.id, replyId)) || diff --git a/src/ue/comments/comments.service.ts b/src/ue/comments/comments.service.ts index 7d30604..3900684 100644 --- a/src/ue/comments/comments.service.ts +++ b/src/ue/comments/comments.service.ts @@ -35,8 +35,10 @@ export class CommentsService { includeDeletedReplied: bypassAnonymousData, }, where: { - ue: { - code: dto.ueCode, + ueof: { + ue: { + code: dto.ueCode, + }, }, }, take: this.config.PAGINATION_PAGE_SIZE, @@ -45,7 +47,7 @@ export class CommentsService { userId, ); const commentCount = await this.prisma.ueComment.count({ - where: { ue: { code: dto.ueCode } }, + where: { ueof: { ue: { code: dto.ueCode } } }, }); // If the user is neither a moderator or the comment author, and the comment is anonymous, // we remove the author from the response @@ -143,11 +145,11 @@ export class CommentsService { * @param ueCode the code of the UE * @returns the last semester done by the {@link user} for the {@link ueCode | ue} */ - async getLastSemesterDoneByUser(userId: string, ueCode: string): Promise { + private async getLastUserSubscription(userId: string, ueCode: string): Promise { return this.prisma.userUeSubscription.findFirst({ where: { - ue: { - code: ueCode, + ueof: { + ueId: ueCode, }, userId, }, @@ -182,7 +184,9 @@ export class CommentsService { }, where: { authorId: userId, - ueId: ue.id, + ueof: { + ueId: ue.code, + }, }, }); return comment.length > 0; @@ -196,6 +200,8 @@ export class CommentsService { * @returns the created {@link UeComment} */ async createComment(body: UeCommentPostDto, userId: string): Promise { + // Use last semester done when creating the comment + const lastSemester = await this.getLastUserSubscription(userId, body.ueCode); return this.prisma.ueComment.create( { args: { @@ -212,15 +218,14 @@ export class CommentsService { id: userId, }, }, - ue: { + ueof: { connect: { - code: body.ueCode, + code: lastSemester.ueofId, }, }, semester: { connect: { - // Use last semester done when creating the comment - code: (await this.getLastSemesterDoneByUser(userId, body.ueCode)).semesterId, + code: lastSemester.semesterId, }, }, }, diff --git a/src/ue/comments/interfaces/comment.interface.ts b/src/ue/comments/interfaces/comment.interface.ts index 5d6a670..def47c2 100644 --- a/src/ue/comments/interfaces/comment.interface.ts +++ b/src/ue/comments/interfaces/comment.interface.ts @@ -25,6 +25,16 @@ const COMMENT_SELECT_FILTER = { }, isAnonymous: true, body: true, + ueof: { + select: { + code: true, + info: { + select: { + language: true, + }, + }, + }, + }, answers: { select: { id: true, diff --git a/src/ue/dto/ue-search.dto.ts b/src/ue/dto/ue-search.dto.ts index 361ea3f..6ecc6ac 100644 --- a/src/ue/dto/ue-search.dto.ts +++ b/src/ue/dto/ue-search.dto.ts @@ -1,5 +1,5 @@ import { Type } from 'class-transformer'; -import { IsNumber, IsPositive, IsString, MaxLength, MinLength, IsOptional } from 'class-validator'; +import { IsNumber, IsPositive, IsString, IsOptional, Length } from 'class-validator'; /** * Query parameters of the request to search UEs. @@ -28,8 +28,7 @@ export class UeSearchDto { creditType?: string; @IsString() - @MaxLength(3) - @MinLength(3) + @Length(3, 3) @IsOptional() availableAtSemester?: string; @@ -38,4 +37,9 @@ export class UeSearchDto { @IsPositive() @IsOptional() page?: number; + + @IsString() + @Length(2) + @IsOptional() + preferredLang?: string; } diff --git a/src/ue/interfaces/ue.interface.ts b/src/ue/interfaces/ue.interface.ts index af93ae1..6c8e50b 100644 --- a/src/ue/interfaces/ue.interface.ts +++ b/src/ue/interfaces/ue.interface.ts @@ -1,79 +1,83 @@ import { Prisma, PrismaClient } from '@prisma/client'; import { generateCustomModel } from '../../prisma/prisma.service'; -import { translationSelect } from '../../utils'; +import { omit, translationSelect } from '../../utils'; const UE_SELECT_FILTER = { select: { - id: true, code: true, - inscriptionCode: true, - name: translationSelect, - info: { + subsequentUes: true, + ueofs: { select: { + code: true, + name: translationSelect, + available: true, + siepId: true, requirements: { select: { code: true, }, }, - comment: translationSelect, - degree: true, - languages: true, - minors: true, - objectives: translationSelect, - program: translationSelect, - }, - }, - openSemester: { - select: { - code: true, - start: true, - end: true, - }, - orderBy: { - start: 'asc', - }, - }, - workTime: { - select: { - cm: true, - td: true, - tp: true, - the: true, - project: true, - internship: true, - }, - }, - credits: { - select: { - credits: true, - category: { + info: { select: { - code: true, - name: true, + language: true, + minors: true, + objectives: translationSelect, + program: translationSelect, }, }, - }, - }, - branchOption: { - select: { - code: true, - name: true, - branch: { + openSemester: { select: { code: true, - name: true, + start: true, + end: true, + }, + orderBy: { + start: 'asc', + }, + }, + workTime: { + select: { + cm: true, + td: true, + tp: true, + the: true, + project: true, + internship: true, + }, + }, + credits: { + select: { + credits: true, + category: { + select: { + code: true, + name: true, + }, + }, + branchOptions: { + select: { + code: true, + name: true, + branch: { + select: { + code: true, + name: true, + }, + }, + }, + }, + }, + }, + starVotes: { + select: { + criterionId: true, + createdAt: true, + value: true, + }, + orderBy: { + criterionId: 'asc', }, }, - }, - }, - starVotes: { - select: { - criterionId: true, - createdAt: true, - value: true, - }, - orderBy: { - criterionId: 'asc', }, }, }, @@ -83,8 +87,18 @@ const UE_SELECT_FILTER = { } as const satisfies Prisma.UeFindManyArgs; export type UnformattedUe = Prisma.UeGetPayload; -export type Ue = Omit & { - starVotes: { [key: string]: number }; +export type Ue = Omit & { + ueofs: Omit[]; + starVotes: { + [key: string]: UeStarVoteEntry[]; + }; + creationYear: number; + updateYear: number; +}; +export type UeStarVoteEntry = { + createdAt: Date; + ueofCode: string; + value: number; }; export function generateCustomUeModel(prisma: PrismaClient) { @@ -94,42 +108,37 @@ export function generateCustomUeModel(prisma: PrismaClient) { function formatUe(_: PrismaClient, ue: UnformattedUe): Ue { // We store rates in a object where the key is the criterion id and the value is a list ratings const starVoteCriteria: { - [key: string]: { - createdAt: Date; - value: number; - }[]; + [key: string]: UeStarVoteEntry[]; } = {}; - for (const starVote of ue.starVotes) { - if (starVote.criterionId in starVoteCriteria) - starVoteCriteria[starVote.criterionId].push({ - createdAt: starVote.createdAt, - value: starVote.value, - }); - else - starVoteCriteria[starVote.criterionId] = [ - { + for (const ueof of ue.ueofs) { + for (const starVote of ueof.starVotes) { + if (starVote.criterionId in starVoteCriteria) + starVoteCriteria[starVote.criterionId].push({ createdAt: starVote.createdAt, + ueofCode: ueof.code, value: starVote.value, - }, - ]; + }); + else + starVoteCriteria[starVote.criterionId] = [ + { + createdAt: starVote.createdAt, + ueofCode: ueof.code, + value: starVote.value, + }, + ]; + } } - // Compute ratings for each criterion, using an exponential decay function - // And turn semester into their respective code. + // Compute creationYear and updateYear + const ueofYears = ue.ueofs + .map((ueof) => Number(ueof.code.match(/\d+$/)?.[0])) + .filter((ueof) => ueof) + .sort(); + return { ...ue, - starVotes: Object.fromEntries(Object.entries(starVoteCriteria).map(([key, entry]) => [key, computeRate(entry)])), + ueofs: ue.ueofs.filter((ueof) => ueof.available).map(omit('available')), + starVotes: starVoteCriteria, + creationYear: 2000 + ueofYears[0], + updateYear: 2000 + ueofYears[ueofYears.length - 1], }; } - -export function computeRate(rates: Array<{ createdAt: Date; value: number }>) { - let coefficients = 0; - let ponderation = 0; - const newestCreationTimestamp = rates.reduce((acc, rate) => Math.max(rate.createdAt.getTime(), acc), 0); - for (const { value, createdAt } of rates) { - const dt = (newestCreationTimestamp - createdAt.getTime()) / 1000; - const dp = Math.exp(-dt / 10e7); - ponderation += dp * value; - coefficients += dp; - } - return Math.round((ponderation / coefficients) * 10) / 10; -} diff --git a/src/ue/ue.controller.ts b/src/ue/ue.controller.ts index 574d7c8..9efdc38 100644 --- a/src/ue/ue.controller.ts +++ b/src/ue/ue.controller.ts @@ -1,4 +1,6 @@ -import { Body, Controller, Delete, Get, Headers, Param, Put, Query } from '@nestjs/common'; +import { Body, Controller, Delete, Get, Headers, Param, Put, Query, Res } from '@nestjs/common'; +import { HttpStatusCode } from 'axios'; +import type { Response } from 'express'; import { UeSearchDto } from './dto/ue-search.dto'; import { UeService } from './ue.service'; import { GetUser, IsPublic, RequireUserType } from '../auth/decorator'; @@ -6,7 +8,7 @@ import { User } from '../users/interfaces/user.interface'; import { UUIDParam } from '../app.pipe'; import { AppException, ERROR_CODE } from '../exceptions'; import { UeRateDto } from './dto/ue-rate.dto'; -import { Ue } from './interfaces/ue.interface'; +import { Ue, UeStarVoteEntry } from './interfaces/ue.interface'; import { Language, UserType } from '@prisma/client'; import { Translation } from '../prisma/types'; @@ -17,155 +19,227 @@ export class UeController { @Get() @IsPublic() async searchUe( + @GetUser() user: User, @Headers('language') language: Language, @Query() queryParams: UeSearchDto, ): Promise> { const res = await this.ueService.searchUes(queryParams, language); return { ...res, - items: res.items.map((ue) => this.formatUeOverview(ue)), + items: res.items.map((ue) => + this.formatUeOverview( + ue, + queryParams.preferredLang ? [queryParams.preferredLang, language] : [language], + user?.branchSubscriptions.map((sub) => [sub.branchOption.code, sub.branchOption.branch.code]).flat() ?? [], // TODO : add more filters + ), + ), }; } @Get('/:ueCode') @IsPublic() - async getUe(@Param('ueCode') ueCode: string, @GetUser() user: User): Promise { - if (!(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); - return this.formatDetailedUe(await this.ueService.getUe(ueCode.toUpperCase()), user); + async getUe( + @GetUser() user: User, + @Param('ueCode') ueCode: string, + @Res({ passthrough: true }) res: Response, + ): Promise { + if (!(await this.ueService.doesUeExist(ueCode))) { + // Check for aliases or throw an error + const alias = await this.ueService.findAlias(ueCode); + if (alias?.standsFor) return res.redirect(HttpStatusCode.MovedPermanently, `./${alias.standsFor}`); + throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); + } + return this.formatDetailedUe(await this.ueService.getUe(ueCode.toUpperCase()), user?.userType); } @Get('/rate/criteria') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async GetRateCriteria() { + async getRateCriteria() { return this.ueService.getRateCriteria(); } @Get('/:ueCode/rate') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async GetRateUe(@Param('ueCode') ueCode: string, @GetUser() user: User) { + async getUeRate(@Param('ueCode') ueCode: string, @GetUser() user: User) { if (!(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); return this.ueService.getRateUe(user.id, ueCode); } - @Put('/:ueCode/rate') + @Put('/ueof/:ueofCode/rate') @RequireUserType('STUDENT') - async RateUe(@Param('ueCode') ueCode: string, @GetUser() user: User, @Body() dto: UeRateDto) { - if (!(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); + async rateUe(@Param('ueofCode') ueofCode: string, @GetUser() user: User, @Body() dto: UeRateDto) { + if (!(await this.ueService.doesUeofExist(ueofCode))) throw new AppException(ERROR_CODE.NO_SUCH_UEOF, ueofCode); if (!(await this.ueService.doesCriterionExist(dto.criterion))) throw new AppException(ERROR_CODE.NO_SUCH_CRITERION); - if (!(await this.ueService.hasAlreadyDoneThisUe(user.id, ueCode))) - throw new AppException(ERROR_CODE.NOT_ALREADY_DONE_UE); - return this.ueService.doRateUe(user.id, ueCode, dto); + if (!(await this.ueService.hasUserAttended(ueofCode, user.id))) + throw new AppException(ERROR_CODE.NOT_ALREADY_DONE_UEOF); + return this.ueService.rateUeof(user.id, ueofCode, dto); } - @Delete('/:ueCode/rate/:criterionId') + @Delete('/ueof/:ueofCode/rate/:criterionId') @RequireUserType('STUDENT', 'FORMER_STUDENT') - async UnRateUe( - @Param('ueCode') ueCode: string, + async unRateUe( + @Param('ueofCode') ueofCode: string, @UUIDParam('criterionId') criterionId: string, @GetUser() user: User, ) { - if (!(await this.ueService.doesUeExist(ueCode))) throw new AppException(ERROR_CODE.NO_SUCH_UE, ueCode); + if (!(await this.ueService.doesUeofExist(ueofCode))) throw new AppException(ERROR_CODE.NO_SUCH_UEOF, ueofCode); if (!(await this.ueService.doesCriterionExist(criterionId))) throw new AppException(ERROR_CODE.NO_SUCH_CRITERION); - if (!(await this.ueService.hasAlreadyRated(user.id, ueCode, criterionId))) - throw new AppException(ERROR_CODE.NOT_ALREADY_RATED_UE, ueCode, criterionId); - return this.ueService.unRateUe(user.id, ueCode, criterionId); + if (!(await this.ueService.hasAlreadyRated(user.id, ueofCode, criterionId))) + throw new AppException(ERROR_CODE.NOT_ALREADY_RATED_UEOF, ueofCode, criterionId); + return this.ueService.unRateUeof(user.id, ueofCode, criterionId); } @Get('/of/me') @RequireUserType('STUDENT') - async getMyUes(@GetUser() user: User): Promise { - return (await this.ueService.getUesOfUser(user.id)).map((ue) => this.formatUeOverview(ue)); + async getMyUes(@GetUser() user: User, @Headers('language') language: Language): Promise { + return (await this.ueService.getUesOfUser(user.id)).map((ue) => + this.formatUeOverview( + ue, + [language], + user.branchSubscriptions.map((sub) => [sub.branchOption.code, sub.branchOption.branch.code]).flat(), + ), + ); } - private formatUeOverview(ue: Ue): UeOverview { + /** This method chooses an UEOF and displays its basic data */ + private formatUeOverview(ue: Ue, langPref: string[], branchOptionPref: string[]): UeOverview { + const lowerCasePref = langPref.map((lang) => lang.toLocaleLowerCase()); + const availableOf = ue.ueofs.filter((ueof) => + branchOptionPref.some((optionPref) => + ueof.credits.some((credit) => credit.branchOptions.some((option) => option.code === optionPref)), + ), + ); + const chosenOf = availableOf.length + ? availableOf.find((ueof) => lowerCasePref.includes(ueof.info.language)) + : ue.ueofs.find((ueof) => lowerCasePref.includes(ueof.info.language)) ?? ue.ueofs[0]; return { code: ue.code, - inscriptionCode: ue.inscriptionCode, - name: ue.name, - credits: ue.credits.map((c) => ({ + name: chosenOf.name, + credits: chosenOf.credits.map((c) => ({ credits: c.credits, category: { code: c.category.code, name: c.category.name, }, - })), - branchOption: ue.branchOption.map((branchOption) => ({ - code: branchOption.code, - name: branchOption.name, - branch: { - code: branchOption.branch.code, - name: branchOption.branch.name, - }, + branchOptions: c.branchOptions, })), info: { - requirements: ue.info.requirements.map((r) => r.code), - comment: ue.info.comment, - degree: ue.info.degree, - languages: ue.info.languages, - minors: ue.info.minors, - objectives: ue.info.objectives, - program: ue.info.program, + requirements: chosenOf.requirements.map((r) => r.code), + languages: ue.ueofs.map((ueof) => ueof.info.language).uniqueValues, }, - openSemester: ue.openSemester.map((semester) => ({ - code: semester.code, - start: semester.start, - end: semester.end, - })), + openSemester: ue.ueofs + .map((ueof) => ueof.openSemester) + .reduce((acc, val) => [...acc, ...val.filter((sem) => acc.every((has) => has.code !== sem.code))], []) + .map((semester) => ({ + code: semester.code, + start: semester.start, + end: semester.end, + })), }; } - private formatDetailedUe(ue: Ue, user?: User): UeDetail { - const format = { + private formatDetailedUe(ue: Ue, userType: UserType): UeDetail { + return { code: ue.code, - inscriptionCode: ue.inscriptionCode, - name: ue.name, - credits: ue.credits.map((c) => ({ - credits: c.credits, - category: { - code: c.category.code, - name: c.category.name, + creationYear: ue.creationYear, + updateYear: ue.updateYear, + ueofs: ue.ueofs.map((ueof) => ({ + code: ueof.code, + name: ueof.name, + credits: ueof.credits.map((c) => ({ + credits: c.credits, + category: { + code: c.category.code, + name: c.category.name, + }, + branchOptions: c.branchOptions.map((branchOption) => ({ + code: branchOption.code, + name: branchOption.name, + branch: { + code: branchOption.branch.code, + name: branchOption.branch.name, + }, + })), + })), + info: { + requirements: ueof.requirements.map((r) => r.code), + language: ueof.info.language, + minors: ueof.info.minors, + objectives: ueof.info.objectives, + program: ueof.info.program, }, - })), - branchOption: ue.branchOption.map((branchOption) => ({ - code: branchOption.code, - name: branchOption.name, - branch: { - code: branchOption.branch.code, - name: branchOption.branch.name, + openSemester: ueof.openSemester.map((semester) => ({ + code: semester.code, + start: semester.start, + end: semester.end, + })), + workTime: { + cm: ueof.workTime.cm, + td: ueof.workTime.td, + tp: ueof.workTime.tp, + the: ueof.workTime.the, + project: ueof.workTime.project, + internship: ueof.workTime.internship, }, + starVotes: + userType === UserType.STUDENT || userType === UserType.FORMER_STUDENT + ? { + // Compute ratings for each criterion, using an exponential decay function + ...Object.fromEntries( + Object.entries(ue.starVotes).map(([criterion, rates]) => [ + criterion, + this.computeRate(rates, ueof.code), + ]), + ), + voteCount: Math.max(...Object.values(ue.starVotes).map((rates) => rates.length)), + } + : undefined, })), - info: { - requirements: ue.info.requirements.map((r) => r.code), - comment: ue.info.comment, - degree: ue.info.degree, - languages: ue.info.languages, - minors: ue.info.minors, - objectives: ue.info.objectives, - program: ue.info.program, - }, - openSemester: ue.openSemester.map((semester) => ({ - code: semester.code, - start: semester.start, - end: semester.end, - })), - workTime: { - cm: ue.workTime.cm, - td: ue.workTime.td, - tp: ue.workTime.tp, - the: ue.workTime.the, - project: ue.workTime.project, - internship: ue.workTime.internship, - }, - } as UeDetail; - if (user?.userType === UserType.STUDENT || user?.userType === UserType.FORMER_STUDENT) - format.starVotes = ue.starVotes; - return format; + }; + } + + public computeRate(rates: UeStarVoteEntry[], targetUeofCode: string) { + function aggregate( + entities: T[], + mapper: (entity: T) => [key: number, value: number], + dtModifier = 1, + decay = 10, + ponderationMultiplier: (entity: T) => number = () => 1, + ) { + let coefficients = 0; + let ponderation = 0; + const latestKey = Math.max(...entities.map((entity) => mapper(entity)[0])); + for (const entity of entities) { + const [key, value] = mapper(entity); + const dt = (latestKey - key) / dtModifier; + const dp = Math.exp(-dt / decay) * ponderationMultiplier(entity); + ponderation += dp * value; + coefficients += dp; + } + return Math.round((ponderation / coefficients) * 10) / 10; + } + // Ponderate the rates of each ueof + const ueofRates = Object.entries(rates.groupyBy((rate) => rate.ueofCode)).map( + ([ueofCode, rates]) => + [ + ueofCode, + Number(ueofCode.slice(0, -2)) || 0, + aggregate(rates, (ent) => [ent.createdAt.getTime(), ent.value], 1000, 10e7), + ] as const, + ); + // Ponderate the rates depending on the ueof + return aggregate( + ueofRates, + (ent) => [ent[1], ent[2]], + 1, + 10, + ([ueofCode]) => (ueofCode === targetUeofCode ? 2 : ueofCode.startsWith(targetUeofCode.slice(0, -3)) ? 1 : 0.5), + ); } } export type UeOverview = { code: string; - inscriptionCode: string; name: Translation; credits: Array<{ credits: number; @@ -173,23 +247,18 @@ export type UeOverview = { code: string; name: string; }; - }>; - branchOption: Array<{ - branch: { + branchOptions: Array<{ + branch: { + code: string; + name: string; + }; code: string; name: string; - }; - code: string; - name: string; + }>; }>; info: { requirements: string[]; - comment: Translation; - degree: string; - languages: string; - minors: string; - objectives: Translation; - program: Translation; + languages: string[]; }; openSemester: Array<{ code: string; @@ -200,44 +269,49 @@ export type UeOverview = { export type UeDetail = { code: string; - inscriptionCode: string; - name: Translation; - credits: Array<{ - credits: number; - category: { - code: string; - name: string; + creationYear: number; + updateYear: number; + ueofs: { + code: string; + name: Translation; + credits: Array<{ + credits: number; + category: { + code: string; + name: string; + }; + branchOptions: Array<{ + branch: { + code: string; + name: string; + }; + code: string; + name: string; + }>; + }>; + info: { + requirements: string[]; + language: string; + minors: string; + objectives: Translation; + program: Translation; }; - }>; - branchOption: Array<{ - branch: { + openSemester: Array<{ code: string; - name: string; + start: Date; + end: Date; + }>; + workTime: { + cm: number; + td: number; + tp: number; + the: number; + project: boolean; + internship: number; }; - code: string; - name: string; - }>; - info: { - requirements: string[]; - comment: Translation; - degree: string; - languages: string; - minors: string; - objectives: Translation; - program: Translation; - }; - openSemester: Array<{ - code: string; - start: Date; - end: Date; - }>; - workTime: { - cm: number; - td: number; - tp: number; - the: number; - project: number; - internship: number; + }[]; + starVotes?: { + [criterionId: string]: number; + voteCount: number; }; - starVotes?: { [criterionId: string]: number }; }; diff --git a/src/ue/ue.service.ts b/src/ue/ue.service.ts index 273f316..1f5f70e 100644 --- a/src/ue/ue.service.ts +++ b/src/ue/ue.service.ts @@ -5,7 +5,6 @@ import { UeRateDto } from './dto/ue-rate.dto'; import { Ue } from './interfaces/ue.interface'; import { Criterion } from './interfaces/criterion.interface'; import { UeRating } from './interfaces/rate.interface'; -import { RawUserUeSubscription } from '../prisma/types'; import { ConfigModule } from '../config/config.module'; import { Language, Prisma } from '@prisma/client'; import { SemesterService } from '../semester/semester.service'; @@ -18,25 +17,9 @@ export class UeService { readonly semesterService: SemesterService, ) {} - async getIdFromCode(ueCode: string): Promise; - async getIdFromCode(ueCodes: string[]): Promise; - async getIdFromCode(ueCodes?: string | string[]) { - const values = ( - await this.prisma.ue.findMany({ - where: { - code: { - in: Array.isArray(ueCodes) ? ueCodes : [ueCodes], - }, - }, - }) - ).map((ue) => ue.id); - if (!Array.isArray(ueCodes)) return values[0]; - return values; - } - /** * Retrieves a page of {@link Ue} matching the user query. This query searchs for a text in - * the ue code, name, comment, objectives and program. The user can restrict his research to a branch, + * the ue code, name, objectives and program. The user can restrict his research to a branch, * a branch option, a credit type or a semester. * @param query the query parameters of this route * @param language the language in which to search for text @@ -58,24 +41,33 @@ export class UeService { }, }, { - inscriptionCode: { - contains: query.q, + ueofs: { + some: { + code: { contains: query.q }, + }, }, }, { - name: { - [language]: { - contains: query.q, + ueofs: { + some: { + name: { + [language]: { + contains: query.q, + }, + }, }, }, }, { - info: { - OR: [ - { comment: { [language]: { contains: query.q } } }, - { objectives: { [language]: { contains: query.q } } }, - { program: { [language]: { contains: query.q } } }, - ], + ueofs: { + some: { + info: { + OR: [ + { objectives: { [language]: { contains: query.q } } }, + { program: { [language]: { contains: query.q } } }, + ], + }, + }, }, }, ], @@ -84,16 +76,24 @@ export class UeService { // Filter per branch option and branch if such a filter is present ...(query.branchOption || query.branch ? { - branchOption: { + ueofs: { some: { - OR: [ - { code: query.branchOption }, - { - branch: { - code: query.branch, + credits: { + some: { + branchOptions: { + some: { + OR: [ + { code: query.branchOption }, + { + branch: { + code: query.branch, + }, + }, + ], + }, }, }, - ], + }, }, }, } @@ -101,10 +101,14 @@ export class UeService { // Filter per credit type ...(query.creditType ? { - credits: { + ueofs: { some: { - category: { - code: query.creditType, + credits: { + some: { + category: { + code: query.creditType, + }, + }, }, }, }, @@ -113,9 +117,13 @@ export class UeService { // Filter per semester ...(query.availableAtSemester ? { - openSemester: { + ueofs: { some: { - code: query.availableAtSemester?.toUpperCase(), + openSemester: { + some: { + code: query.availableAtSemester.toUpperCase(), + }, + }, }, }, } @@ -152,66 +160,66 @@ export class UeService { } /** - * Retrieves the last semester done by a user for a given ue - * @remarks The user must not be null - * @param userId the user to retrieve semesters of - * @param ueCode the code of the UE - * @returns the last semester done by the {@link user} for the {@link ueCode | ue} + * Checks whether an ue exists + * @param ueCode the code of the ue to check + * @returns whether the ue exists */ - async getLastSemesterDoneByUser(userId: string, ueCode: string): Promise { - return this.prisma.userUeSubscription.findFirst({ + async doesUeExist(ueCode: string) { + return !!(await this.prisma.ue.count({ where: { - ue: { - code: ueCode, - }, - userId, + code: ueCode, }, - orderBy: { - semester: { - end: 'desc', - }, + })); + } + + async findAlias(aliasCode: string) { + return this.prisma.ueAlias.findUnique({ + where: { + code: aliasCode, }, }); } - /** - * Checks whether an ue exists - * @param ueCode the code of the ue to check - * @returns whether the ue exists - */ - async doesUeExist(ueCode: string) { - return ( - (await this.prisma.ue.count({ - where: { - code: ueCode, - }, - })) != 0 - ); + async doesUeofExist(ueofCode: string) { + return !!(await this.prisma.ueof.count({ + where: { + code: ueofCode, + }, + })); } /** - * Checks whether a user has already done an ue - * @remarks The user must not be null + * Retrieves the amount of UEOF the given {@link userId | user} has attended. + * Not only this method can be used to retrieve the precise count of matching ueofs done by the user, + * but also in order to check if a user has attended a specific UEOF. + * The key feature of this function is that UEOF matching is done on both UEOF and UE codes, + * allowing to check if a user has attended a specific UEOF or a specific UE. + * + * @param ueCodeOrUeofCode the code of the ue or the ueof to check * @param userId the user to check - * @param ueCode the code of the ue to check - * @returns whether the {@link user} has already done the {@link ueCode | ue} + * @param semester provide a semester code to filter the ueofs by semester + * @returns the amount of UEOF the {@link userId | user} has attended + * + * @example + * ```typescript + * const user: User = ...; + * const ueCode: string = 'MT01'; + * // Check user has already done MT01 + * if (!(await ueService.hasUserAttended(ueCode, user.id))) { + * throw new AppException(ERROR_CODE.DUMMY_ERROR, 'This feature is only available for students who have attended MT01'); + * } + * ``` */ - async hasAlreadyDoneThisUe(userId: string, ueCode: string) { - return (await this.getLastSemesterDoneByUser(userId, ueCode)) != null; - } - - async hasDoneThisUeInSemester(userId: string, ueCode: string, semesterCode: string) { - return ( - (await this.prisma.userUeSubscription.count({ - where: { - semesterId: semesterCode, - ue: { - code: ueCode, - }, - userId, + async hasUserAttended(ueCodeOrUeofCode: string, userId: string, semester?: string): Promise { + return this.prisma.userUeSubscription.count({ + where: { + userId: userId ?? null, // We want the filter to be applied in every query + semesterId: semester || undefined, // This filter should be applied only if semester is not null + ueof: { + OR: [{ code: ueCodeOrUeofCode }, { ueId: ueCodeOrUeofCode }], }, - })) != 0 - ); + }, + }); } /** @@ -229,12 +237,12 @@ export class UeService { ); } - async hasAlreadyRated(userId: string, ueCode: string, criterionId: string) { + async hasAlreadyRated(userId: string, ueofCode: string, criterionId: string) { return ( (await this.prisma.ueStarVote.count({ where: { - ue: { - code: ueCode, + ueof: { + code: ueofCode, }, userId, criterionId, @@ -258,34 +266,50 @@ export class UeService { * @param ueCode the code of the ue to fetch the rates of * @returns the rates of the {@link ueCode | ue} for the {@link user} */ - async getRateUe(userId: string, ueCode: string): Promise { - const ue = await this.prisma.ue.findUnique({ + async getRateUe( + userId: string, + ueCode: string, + ): Promise<{ + [ueofCode: string]: UeRating[]; + }> { + const ueofs = await this.prisma.ueof.findMany({ where: { - code: ueCode, - }, - }); - return this.prisma.ueStarVote.findMany({ - where: { - userId: userId, - ueId: ue.id, + ue: { + code: ueCode, + }, }, }); + return Object.fromEntries( + await Promise.all( + ueofs.map( + async (ueof) => + [ + ueof.code, + await this.prisma.ueStarVote.findMany({ + where: { + userId: userId, + ueofId: ueof.code, + }, + }), + ] as const, + ), + ), + ); } /** * Creates or updates a rating for a given ue * @remarks The user must not be null and the ue must exist * @param userId the user rating the ue - * @param ueCode the code of the ue to rate + * @param ueofCode the code of the ue to rate * @param dto the rating to apply - * @returns the new rate of the {@link ueCode | ue} for the {@link user} + * @returns the new rate of the {@link ueofCode | ue} for the {@link user} */ - async doRateUe(userId: string, ueCode: string, dto: UeRateDto): Promise { - const ueId = await this.getUeIdFromCode(ueCode); + async rateUeof(userId: string, ueofCode: string, dto: UeRateDto): Promise { return this.prisma.ueStarVote.upsert({ where: { - ueId_userId_criterionId: { - ueId, + ueofId_userId_criterionId: { + ueofId: ueofCode, userId, criterionId: dto.criterion, }, @@ -293,7 +317,7 @@ export class UeService { create: { value: dto.value, criterionId: dto.criterion, - ueId, + ueofId: ueofCode, userId, }, update: { @@ -302,12 +326,11 @@ export class UeService { }); } - async unRateUe(userId: string, ueCode: string, criterionId: string): Promise { - const ueId = await this.getUeIdFromCode(ueCode); + async unRateUeof(userId: string, ueofCode: string, criterionId: string): Promise { return this.prisma.ueStarVote.delete({ where: { - ueId_userId_criterionId: { - ueId, + ueofId_userId_criterionId: { + ueofId: ueofCode, userId, criterionId, }, @@ -320,19 +343,19 @@ export class UeService { if (currentSemester === null) return []; return this.prisma.ue.findMany({ where: { - usersSubscriptions: { + ueofs: { some: { - userId, - semester: { - code: currentSemester.code, + usersSubscriptions: { + some: { + userId, + semester: { + code: currentSemester.code, + }, + }, }, }, }, }, }); } - - private async getUeIdFromCode(ueCode: string): Promise { - return (await this.prisma.withDefaultBehaviour.ue.findUnique({ where: { code: ueCode }, select: { id: true } })).id; - } } diff --git a/src/validation.ts b/src/validation.ts index b4a89a6..24c6cab 100644 --- a/src/validation.ts +++ b/src/validation.ts @@ -19,6 +19,7 @@ const mappedErrors = { isEnum: ERROR_CODE.PARAM_NOT_ENUM, isDate: ERROR_CODE.PARAM_NOT_DATE, isUuid: ERROR_CODE.PARAM_NOT_UUID, + isLength: ERROR_CODE.PARAM_INVALID_SIZE, maxLength: ERROR_CODE.PARAM_TOO_LONG, minLength: ERROR_CODE.PARAM_TOO_SHORT, arrayMinSize: ERROR_CODE.PARAM_SIZE_TOO_SMALL, diff --git a/test/declarations.d.ts b/test/declarations.d.ts index 3ef3a8a..e33fc2c 100644 --- a/test/declarations.d.ts +++ b/test/declarations.d.ts @@ -1,5 +1,5 @@ import { ERROR_CODE, ErrorData, ExtrasTypeBuilder } from '../src/exceptions'; -import { UeComment } from 'src/ue/interfaces/comment.interface'; +import { UeComment } from 'src/ue/comments/interfaces/comment.interface'; import { UeCommentReply } from 'src/ue/comments/interfaces/comment-reply.interface'; import { UeRating } from 'src/ue/interfaces/rate.interface'; import { FakeUeAnnalType } from './utils/fakedb'; @@ -48,11 +48,11 @@ declare module './declarations' { * depending on the {@link created} property. */ expectUeComment( - comment: JsonLikeVariant>, + comment: JsonLikeVariant> & { ue: FakeUe }, created = false, ): this; /** expects to return the given {@link commentPage | page of comments} */ - expectUeComments(commentPage: JsonLikeVariant>): this; + expectUeComments(commentPage: Pagination): this; /** * expects to return the given {@link reply} * The HTTP Status code may be 200 or 204, depending on the {@link created} property. diff --git a/test/declarations.ts b/test/declarations.ts index 075f9fd..5209d8d 100644 --- a/test/declarations.ts +++ b/test/declarations.ts @@ -15,12 +15,12 @@ import { isArray } from 'class-validator'; import { Language } from '@prisma/client'; /** Shortcut function for `this.expectStatus(200).expectJsonLike` */ -function expect(obj: JsonLikeVariant) { - return (this).expectStatus(HttpStatus.OK).expectJsonMatchStrict(obj); +function expect(this: Spec, obj: JsonLikeVariant) { + return this.expectStatus(HttpStatus.OK).expectJsonMatchStrict(obj); } /** Shortcut function for `this.expectStatus(200|204).expectJsonLike` */ -function expectOkOrCreate(obj: JsonLikeVariant, created = false) { - return (this).expectStatus(created ? HttpStatus.CREATED : HttpStatus.OK).expectJsonLike(obj); +function expectOkOrCreate(this: Spec, obj: JsonLikeVariant, created = false) { + return this.expectStatus(created ? HttpStatus.CREATED : HttpStatus.OK).expectJsonLike(obj); } export function deepDateToString(obj: T): JsonLikeVariant { @@ -34,19 +34,21 @@ export function deepDateToString(obj: T): JsonLikeVariant { function ueOverviewExpectation(ue: FakeUe, spec: Spec) { return { - ...omit(ue, 'id', 'validationRate', 'createdAt', 'updatedAt', 'openSemesters', 'workTime'), + code: ue.code, name: getTranslation(ue.name, spec.language), + credits: ue.credits.map((credit) => ({ + ...omit(credit, 'id', 'ueofId', 'categoryId', 'branchOptions'), + branchOptions: credit.branchOptions.map((branchOption) => ({ + ...pick(branchOption, 'code', 'name'), + branch: pick(branchOption.branch, 'code', 'name'), + })), + })), info: { - ...omit(ue.info, 'id', 'comment', 'program', 'objectives'), - comment: getTranslation(ue.info.comment, spec.language), + ...omit(ue.info, 'id', 'program', 'objectives', 'language'), + languages: [ue.info.language], program: getTranslation(ue.info.program, spec.language), objectives: getTranslation(ue.info.objectives, spec.language), }, - credits: ue.credits.map((credit) => omit(credit, 'id', 'ueId', 'categoryId')), - branchOption: ue.branchOption.map((branchOption) => ({ - ...pick(branchOption, 'code', 'name'), - branch: pick(branchOption.branch, 'code', 'name'), - })), openSemester: ue.openSemesters.map((semester) => ({ ...semester, start: semester.start.toISOString(), @@ -69,31 +71,38 @@ Spec.prototype.expectAppError = function ( error: (args as string[]).reduce((arg, extra) => arg.replaceAll('%', extra), ErrorData[errorCode].message), }); }; -Spec.prototype.expectUe = function (ue: FakeUe, rates: Array<{ criterionId: string; value: number }> = []) { +Spec.prototype.expectUe = function (ue: FakeUe, rates: Array<{ criterionId: string; value: number }>) { return (this).expectStatus(HttpStatus.OK).expectJsonMatchStrict( deepDateToString({ - ...omit(ue, 'id', 'validationRate', 'createdAt', 'updatedAt', 'openSemesters'), - name: getTranslation(ue.name, this.language), - info: { - ...omit(ue.info, 'id'), - objectives: getTranslation(ue.info.objectives, this.language), - comment: getTranslation(ue.info.comment, this.language), - program: getTranslation(ue.info.program, this.language), - }, - workTime: omit(ue.workTime, 'id', 'ueId'), - credits: ue.credits.map((credit) => omit(credit, 'id', 'ueId', 'categoryId')), - branchOption: ue.branchOption.map((branchOption) => ({ - ...pick(branchOption, 'code', 'name'), - branch: pick(branchOption.branch, 'code', 'name'), - })), - openSemester: ue.openSemesters - .mappedSort((semester) => semester.start.toISOString()) - .map((semester) => ({ - ...semester, - start: semester.start.toISOString(), - end: semester.end.toISOString(), - })), - starVotes: Object.fromEntries(rates.map((rate) => [rate.criterionId, rate.value])), + code: ue.code, + creationYear: 2000 + Number(ue.ueofCode.match(/\d+$/)?.[0] ?? 23), + updateYear: 2000 + Number(ue.ueofCode.match(/\d+$/)?.[0] ?? 23), + ...(rates ? { starVotes: Object.fromEntries(rates.map((rate) => [rate.criterionId, rate.value])) } : {}), + ueofs: [ + { + name: getTranslation(ue.name, this.language), + credits: ue.credits.map((credit) => ({ + ...omit(credit, 'id', 'ueofId', 'categoryId', 'branchOptions'), + branchOptions: credit.branchOptions.map((branchOption) => ({ + ...pick(branchOption, 'code', 'name'), + branch: pick(branchOption.branch, 'code', 'name'), + })), + })), + info: { + ...omit(ue.info, 'id'), + objectives: getTranslation(ue.info.objectives, this.language), + program: getTranslation(ue.info.program, this.language), + }, + openSemester: ue.openSemesters + .mappedSort((semester) => semester.start.toISOString()) + .map((semester) => ({ + ...semester, + start: semester.start.toISOString(), + end: semester.end.toISOString(), + })), + workTime: omit(ue.workTime, 'id', 'ueofId'), + }, + ], }), ); }; @@ -123,8 +132,18 @@ Spec.prototype.expectUesWithPagination = function (app: AppProvider, ues: FakeUe itemsPerPage: app().get(ConfigModule).PAGINATION_PAGE_SIZE, }); }; -Spec.prototype.expectUeComment = expectOkOrCreate>; -Spec.prototype.expectUeComments = function expect(obj: Pagination) { +Spec.prototype.expectUeComment = function expect(this: Spec, obj, created = false) { + return this.expectStatus(created ? HttpStatus.CREATED : HttpStatus.OK).expectJsonLike({ + ...omit(obj as any, 'ue', 'ueofId'), + ueof: { + code: obj.ue.ueofCode, + info: { + language: obj.ue.info.language, + }, + }, + }); +}; +Spec.prototype.expectUeComments = function expect(obj) { return (this).expectStatus(HttpStatus.OK).expectJsonMatchStrict({ itemCount: obj.itemCount, itemsPerPage: obj.itemsPerPage, @@ -141,6 +160,12 @@ Spec.prototype.expectUeComments = function expect(obj: Pagination) { 'upvoted', 'upvotes', ), + ueof: { + code: comment.ue.ueofCode, + info: { + language: comment.ue.info.language, + }, + }, createdAt: comment.createdAt.toISOString(), updatedAt: comment.updatedAt.toISOString(), answers: comment.answers.map((answer) => ({ diff --git a/test/e2e/auth/cas-sign-up.e2e-spec.ts b/test/e2e/auth/cas-sign-up.e2e-spec.ts index 189c8f8..1990565 100644 --- a/test/e2e/auth/cas-sign-up.e2e-spec.ts +++ b/test/e2e/auth/cas-sign-up.e2e-spec.ts @@ -34,7 +34,7 @@ const CasSignUpE2ESpec = e2eSuite('/auth/signup/cas', (app) => { start: new Date(), end: new Date(), }); - const ue = fakedb.createUe(app); + const ue = fakedb.createUe(app, { branchOptions: [branchOption] }); beforeAll(() => ldapServer.start()); afterAll(() => ldapServer.stop()); diff --git a/test/e2e/ue/annals/delete-annal.e2e-spec.ts b/test/e2e/ue/annals/delete-annal.e2e-spec.ts index 8261cce..23e9798 100644 --- a/test/e2e/ue/annals/delete-annal.e2e-spec.ts +++ b/test/e2e/ue/annals/delete-annal.e2e-spec.ts @@ -23,7 +23,7 @@ const DeleteAnnal = e2eSuite('DELETE /ue/annals/{annalId}', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); createUeSubscription(app, { user: senderUser, ue, semester }); const annal_validated = createAnnal(app, { semester, sender: senderUser, type: annalType, ue }); @@ -67,9 +67,6 @@ const DeleteAnnal = e2eSuite('DELETE /ue/annals/{annalId}', (app) => { sender: pick(senderUser, 'id', 'firstName', 'lastName'), createdAt: annal_validated.createdAt.toISOString(), updatedAt: JsonLike.ANY_DATE, - ue: { - code: ue.code, - }, }); return app() .get(PrismaService) diff --git a/test/e2e/ue/annals/get-annal-file.e2e-spec.ts b/test/e2e/ue/annals/get-annal-file.e2e-spec.ts index 82f81be..81e1a51 100644 --- a/test/e2e/ue/annals/get-annal-file.e2e-spec.ts +++ b/test/e2e/ue/annals/get-annal-file.e2e-spec.ts @@ -22,7 +22,7 @@ const GetAnnalFile = e2eSuite('GET /ue/annals/{annalId}', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); createUeSubscription(app, { user: senderUser, ue, semester }); const annal_not_validated = createAnnal( app, diff --git a/test/e2e/ue/annals/get-annal-metadata.e2e-spec.ts b/test/e2e/ue/annals/get-annal-metadata.e2e-spec.ts index 558d10e..6201439 100644 --- a/test/e2e/ue/annals/get-annal-metadata.e2e-spec.ts +++ b/test/e2e/ue/annals/get-annal-metadata.e2e-spec.ts @@ -19,7 +19,7 @@ const GetAnnalMetadata = e2eSuite('GET /ue/annals/metadata', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); createUeSubscription(app, { user: ueUser, ue, semester }); it('should return a 401 as user is not authenticated', () => { diff --git a/test/e2e/ue/annals/get-annals.e2e-spec.ts b/test/e2e/ue/annals/get-annals.e2e-spec.ts index eda55c7..40e3e83 100644 --- a/test/e2e/ue/annals/get-annals.e2e-spec.ts +++ b/test/e2e/ue/annals/get-annals.e2e-spec.ts @@ -25,7 +25,7 @@ const GetAnnal = e2eSuite('GET /ue/annals', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); createUeSubscription(app, { user: senderUser, ue, semester }); const annal_not_validated = createAnnal( app, @@ -105,7 +105,7 @@ const GetAnnal = e2eSuite('GET /ue/annals', (app) => { const formatAnnalFile = (from: Partial): JsonLikeVariant => { return { - ...pick(from, 'id', 'semesterId', 'status', 'sender', 'type', 'ue'), + ...pick(from, 'id', 'semesterId', 'status', 'sender', 'type', 'ueof'), createdAt: from.createdAt?.toISOString(), updatedAt: from.updatedAt?.toISOString(), }; diff --git a/test/e2e/ue/annals/patch-annal.e2e-spec.ts b/test/e2e/ue/annals/patch-annal.e2e-spec.ts index 1e88364..d5695bf 100644 --- a/test/e2e/ue/annals/patch-annal.e2e-spec.ts +++ b/test/e2e/ue/annals/patch-annal.e2e-spec.ts @@ -22,7 +22,7 @@ const EditAnnal = e2eSuite('PATCH /ue/annals/{annalId}', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); createUeSubscription(app, { user: senderUser, ue, semester }); const annal_validated = createAnnal(app, { semester, sender: senderUser, type: annalType, ue }); const annal_not_uploaded = createAnnal( @@ -106,9 +106,6 @@ const EditAnnal = e2eSuite('PATCH /ue/annals/{annalId}', (app) => { id: annal_validated.id, createdAt: annal_validated.createdAt.toISOString(), updatedAt: JsonLike.ANY_DATE, - ue: { - code: ue.code, - }, }); }); }); diff --git a/test/e2e/ue/annals/upload-annal.e2e-spec.ts b/test/e2e/ue/annals/upload-annal.e2e-spec.ts index 518990b..480cac6 100644 --- a/test/e2e/ue/annals/upload-annal.e2e-spec.ts +++ b/test/e2e/ue/annals/upload-annal.e2e-spec.ts @@ -23,7 +23,7 @@ const PostAnnal = e2eSuite('POST-PUT /ue/annals', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); createUeSubscription(app, { user: senderUser, ue, semester }); it('should return a 401 as user is not authenticated', () => { diff --git a/test/e2e/ue/comments/delete-comment.e2e-spec.ts b/test/e2e/ue/comments/delete-comment.e2e-spec.ts index 9dfd6f5..bc83595 100644 --- a/test/e2e/ue/comments/delete-comment.e2e-spec.ts +++ b/test/e2e/ue/comments/delete-comment.e2e-spec.ts @@ -19,7 +19,7 @@ const DeleteComment = e2eSuite('DELETE /ue/comments/{commentId}', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comment1 = createComment(app, { user, ue, semester }); createCommentUpvote(app, { user, comment: comment1 }); @@ -57,6 +57,7 @@ const DeleteComment = e2eSuite('DELETE /ue/comments/{commentId}', (app) => { .withBearerToken(user.token) .delete(`/ue/comments/${comment1.id}`) .expectUeComment({ + ue, id: comment1.id, author: { id: comment1.authorId, diff --git a/test/e2e/ue/comments/delete-reply.e2e-spec.ts b/test/e2e/ue/comments/delete-reply.e2e-spec.ts index c7257f7..50dec1f 100644 --- a/test/e2e/ue/comments/delete-reply.e2e-spec.ts +++ b/test/e2e/ue/comments/delete-reply.e2e-spec.ts @@ -19,7 +19,7 @@ const DeleteCommentReply = e2eSuite('DELETE /ue/comments/reply/{replyId}', (app) const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comment1 = createComment(app, { user, ue, semester }); const reply = createCommentReply(app, { user, comment: comment1 }); diff --git a/test/e2e/ue/comments/delete-upvote.e2e-spec.ts b/test/e2e/ue/comments/delete-upvote.e2e-spec.ts index 3615c45..cf781f4 100644 --- a/test/e2e/ue/comments/delete-upvote.e2e-spec.ts +++ b/test/e2e/ue/comments/delete-upvote.e2e-spec.ts @@ -19,7 +19,7 @@ const DeleteUpvote = e2eSuite('DELETE /ue/comments/{commentId}/upvote', (app) => const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comment1 = createComment(app, { user, ue, semester }); const upvote = createCommentUpvote(app, { user: user2, comment: comment1 }); diff --git a/test/e2e/ue/comments/get-comment-from-id.e2e-spec.ts b/test/e2e/ue/comments/get-comment-from-id.e2e-spec.ts index af8a6f9..91cf636 100644 --- a/test/e2e/ue/comments/get-comment-from-id.e2e-spec.ts +++ b/test/e2e/ue/comments/get-comment-from-id.e2e-spec.ts @@ -10,7 +10,9 @@ const GetCommentFromIdE2ESpec = e2eSuite('GET /ue/comments/:commentId', (app) => const user = fakedb.createUser(app); const user2 = fakedb.createUser(app, { login: 'user2', studentId: 3 }); const semester = fakedb.createSemester(app); - const ue = fakedb.createUe(app, { code: `XX01`, openSemesters: [semester] }); + const branch = fakedb.createBranch(app); + const branchOption = fakedb.createBranchOption(app, { branch }); + const ue = fakedb.createUe(app, { branchOptions: [branchOption] }, { code: `XX01`, openSemesters: [semester] }); const comment = fakedb.createComment(app, { user, ue, semester }); fakedb.createCommentUpvote(app, { user: user2, comment }); const reply = fakedb.createCommentReply(app, { user, comment }, { body: 'HelloWorld' }); @@ -41,13 +43,13 @@ const GetCommentFromIdE2ESpec = e2eSuite('GET /ue/comments/:commentId', (app) => .withBearerToken(user.token) .get(`/ue/comments/${comment.id}`) .expectUeComment({ + ue, ...(omit( comment, 'semesterId', 'authorId', 'deletedAt', 'validatedAt', - 'ueId', 'lastValidatedBody', ) as Required), answers: [ @@ -76,13 +78,13 @@ const GetCommentFromIdE2ESpec = e2eSuite('GET /ue/comments/:commentId', (app) => .withBearerToken(user2.token) .get(`/ue/comments/${comment.id}`) .expectUeComment({ + ue, ...(omit( comment, 'semesterId', 'authorId', 'deletedAt', 'validatedAt', - 'ueId', 'lastValidatedBody', ) as Required), answers: [ diff --git a/test/e2e/ue/comments/get-comment.e2e-spec.ts b/test/e2e/ue/comments/get-comment.e2e-spec.ts index d11d766..c59a974 100644 --- a/test/e2e/ue/comments/get-comment.e2e-spec.ts +++ b/test/e2e/ue/comments/get-comment.e2e-spec.ts @@ -22,7 +22,7 @@ const GetCommentsE2ESpec = e2eSuite('GET /ue/comments', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comments: FakeComment[] = []; comments.push( createComment( @@ -108,7 +108,7 @@ const GetCommentsE2ESpec = e2eSuite('GET /ue/comments', (app) => { .slice(0, app().get(ConfigModule).PAGINATION_PAGE_SIZE) .map((comment) => { if (comment.isAnonymous && comment.author.id !== user.id) delete comment.author; - return comment; + return { ...comment, ue }; }), itemCount: comments.length, itemsPerPage: app().get(ConfigModule).PAGINATION_PAGE_SIZE, @@ -154,7 +154,7 @@ const GetCommentsE2ESpec = e2eSuite('GET /ue/comments', (app) => { .slice(app().get(ConfigModule).PAGINATION_PAGE_SIZE, app().get(ConfigModule).PAGINATION_PAGE_SIZE * 2) .map((comment) => { if (comment.isAnonymous && comment.author.id !== user.id) delete comment.author; - return comment; + return { ...comment, ue }; }), itemCount: comments.length, itemsPerPage: app().get(ConfigModule).PAGINATION_PAGE_SIZE, @@ -188,6 +188,7 @@ const GetCommentsE2ESpec = e2eSuite('GET /ue/comments', (app) => { ? (b.createdAt).getTime() - (a.createdAt).getTime() : b.upvotes - a.upvotes, ) + .map((comment) => ({ ...comment, ue })) .slice(0, app().get(ConfigModule).PAGINATION_PAGE_SIZE), itemCount: comments.length, itemsPerPage: app().get(ConfigModule).PAGINATION_PAGE_SIZE, diff --git a/test/e2e/ue/comments/post-comment.e2e-spec.ts b/test/e2e/ue/comments/post-comment.e2e-spec.ts index 156d39e..e4fdfac 100644 --- a/test/e2e/ue/comments/post-comment.e2e-spec.ts +++ b/test/e2e/ue/comments/post-comment.e2e-spec.ts @@ -19,7 +19,7 @@ const PostCommment = e2eSuite('POST /ue/comments', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); createUeSubscription(app, { user: user2, ue, semester }); it('should return a 401 as user is not authenticated', () => { @@ -96,6 +96,7 @@ const PostCommment = e2eSuite('POST /ue/comments', (app) => { .expectUeComment( { id: JsonLike.ANY_UUID, + ue, author: { id: user2.id, firstName: user2.firstName, @@ -144,6 +145,7 @@ const PostCommment = e2eSuite('POST /ue/comments', (app) => { }) .expectUeComment( { + ue, id: JsonLike.ANY_UUID, author: { id: user2.id, diff --git a/test/e2e/ue/comments/post-reply.e2e-spec.ts b/test/e2e/ue/comments/post-reply.e2e-spec.ts index 03e35c7..610a0bc 100644 --- a/test/e2e/ue/comments/post-reply.e2e-spec.ts +++ b/test/e2e/ue/comments/post-reply.e2e-spec.ts @@ -18,7 +18,7 @@ const PostCommmentReply = e2eSuite('POST /ue/comments/{commentId}/reply', (app) const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comment = createComment(app, { ue, user, semester }); createUeSubscription(app, { user, ue, semester }); diff --git a/test/e2e/ue/comments/post-upvote.e2e-spec.ts b/test/e2e/ue/comments/post-upvote.e2e-spec.ts index 968f018..f1cfc52 100644 --- a/test/e2e/ue/comments/post-upvote.e2e-spec.ts +++ b/test/e2e/ue/comments/post-upvote.e2e-spec.ts @@ -19,7 +19,7 @@ const PostUpvote = e2eSuite('POST /ue/comments/{commentId}/upvote', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comment = createComment(app, { ue, user, semester }); it('should return a 401 as user is not authenticated', () => { diff --git a/test/e2e/ue/comments/update-comment.e2e-spec.ts b/test/e2e/ue/comments/update-comment.e2e-spec.ts index c0cb281..b4a7573 100644 --- a/test/e2e/ue/comments/update-comment.e2e-spec.ts +++ b/test/e2e/ue/comments/update-comment.e2e-spec.ts @@ -19,7 +19,7 @@ const UpdateComment = e2eSuite('PATCH /ue/comments/{commentId}', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comment = createComment(app, { ue, user, semester }); createCommentUpvote(app, { user: user2, comment }); @@ -100,6 +100,7 @@ const UpdateComment = e2eSuite('PATCH /ue/comments/{commentId}', (app) => { isAnonymous: true, }) .expectUeComment({ + ue, id: JsonLike.ANY_UUID, author: { id: user.id, @@ -133,6 +134,7 @@ const UpdateComment = e2eSuite('PATCH /ue/comments/{commentId}', (app) => { isAnonymous: false, }) .expectUeComment({ + ue, id: JsonLike.ANY_UUID, author: { id: user.id, diff --git a/test/e2e/ue/comments/update-reply.e2e-spec.ts b/test/e2e/ue/comments/update-reply.e2e-spec.ts index 019e1db..93a0e72 100644 --- a/test/e2e/ue/comments/update-reply.e2e-spec.ts +++ b/test/e2e/ue/comments/update-reply.e2e-spec.ts @@ -19,7 +19,7 @@ const UpdateCommentReply = e2eSuite('PATCH /ue/comments/reply/{replyId}', (app) const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const comment = createComment(app, { ue, user, semester }); const reply = createCommentReply(app, { user, comment }); diff --git a/test/e2e/ue/delete-rate.e2e-spec.ts b/test/e2e/ue/delete-rate.e2e-spec.ts index 01bd7c3..a639da4 100644 --- a/test/e2e/ue/delete-rate.e2e-spec.ts +++ b/test/e2e/ue/delete-rate.e2e-spec.ts @@ -19,7 +19,7 @@ const DeleteRate = e2eSuite('DELETE /ue/{ueCode}/rate/{critetionId}', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const criterion = createCriterion(app); createUeSubscription(app, { user, ue, semester }); const rating = createUeRating(app, { user, ue, criterion }); @@ -33,7 +33,7 @@ const DeleteRate = e2eSuite('DELETE /ue/{ueCode}/rate/{critetionId}', (app) => { .spec() .withBearerToken(user2.token) .delete(`/ue/${ue.code}/rate/${criterion.id}`) - .expectAppError(ERROR_CODE.NOT_ALREADY_RATED_UE, ue.code, criterion.id); + .expectAppError(ERROR_CODE.NOT_ALREADY_RATED_UEOF, ue.code, criterion.id); }); it('should return a 404 as the UE does not exist', () => { diff --git a/test/e2e/ue/get-my-ues.e2e-spec.ts b/test/e2e/ue/get-my-ues.e2e-spec.ts index 52cfada..0370fdd 100644 --- a/test/e2e/ue/get-my-ues.e2e-spec.ts +++ b/test/e2e/ue/get-my-ues.e2e-spec.ts @@ -1,24 +1,33 @@ import { e2eSuite } from '../../utils/test_utils'; import * as pactum from 'pactum'; -import { createSemester, createUe, createUeSubscription, createUser } from '../../utils/fakedb'; +import { + createBranch, + createBranchOption, + createSemester, + createUe, + createUeSubscription, + createUser, +} from '../../utils/fakedb'; import { ERROR_CODE } from '../../../src/exceptions'; const GetMyUesE2ESpec = e2eSuite('GET ue/of/me', (app) => { const user = createUser(app); - const ue = createUe(app); + const branch = createBranch(app); + const branchOption = createBranchOption(app, { branch }); + const ue = createUe(app, { branchOptions: [branchOption] }); const semester = createSemester(app, { start: new Date(Date.now() - 30 * 24 * 3_600_000), end: new Date(Date.now() + 30 * 24 * 3_600_000), }); createUeSubscription(app, { user, ue, semester }); - const ue2 = createUe(app); + const ue2 = createUe(app, { branchOptions: [branchOption] }); const semester2 = createSemester(app, { start: new Date(Date.now() - 90 * 24 * 3_600_000), end: new Date(Date.now() - 30 * 24 * 3_600_000), }); createUeSubscription(app, { user, ue: ue2, semester: semester2 }); const user2 = createUser(app); - const ue3 = createUe(app); + const ue3 = createUe(app, { branchOptions: [branchOption] }); createUeSubscription(app, { user: user2, ue: ue3, semester }); const formerStudent = createUser(app, { userType: 'FORMER_STUDENT' }); diff --git a/test/e2e/ue/get-ue-rate.e2e-spec.ts b/test/e2e/ue/get-ue-rate.e2e-spec.ts index fb7b520..8a91f4e 100644 --- a/test/e2e/ue/get-ue-rate.e2e-spec.ts +++ b/test/e2e/ue/get-ue-rate.e2e-spec.ts @@ -17,7 +17,7 @@ const GetRateE2ESpec = e2eSuite('GET /ue/{ueCode}/rate', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const c1 = createCriterion(app); const c2 = createCriterion(app); createUeRating(app, { ue, criterion: c1, user }, { value: 1 }); diff --git a/test/e2e/ue/get.e2e-spec.ts b/test/e2e/ue/get.e2e-spec.ts index 57327ca..9dfe226 100644 --- a/test/e2e/ue/get.e2e-spec.ts +++ b/test/e2e/ue/get.e2e-spec.ts @@ -11,9 +11,10 @@ import { FakeUeStarVote, } from '../../utils/fakedb'; import { e2eSuite } from '../../utils/test_utils'; +import { UeController } from '../../../src/ue/ue.controller'; import * as pactum from 'pactum'; import { ERROR_CODE } from '../../../src/exceptions'; -import { computeRate } from '../../../src/ue/interfaces/ue.interface'; +import { UserType } from '@prisma/client'; const GetE2ESpec = e2eSuite('GET /ue/{ueCode}', (app) => { const user = createUser(app); @@ -21,6 +22,11 @@ const GetE2ESpec = e2eSuite('GET /ue/{ueCode}', (app) => { login: 'user2', studentId: 2, }); + const user3 = createUser(app, { + login: 'user3', + studentId: 3, + userType: UserType.EMPLOYEE, + }); const semesters = [createSemester(app), createSemester(app)]; const branches = [createBranch(app), createBranch(app)]; const branchOptions = [ @@ -40,26 +46,32 @@ const GetE2ESpec = e2eSuite('GET /ue/{ueCode}', (app) => { const ues: FakeUe[] = []; for (let i = 0; i < 30; i++) ues.push( - createUe(app, { - code: `XX${`${i}`.padStart(2, '0')}`, - credits: [ - { - category: { - code: i % 3 == 0 ? 'CS' : 'TM', - name: i % 3 == 0 ? 'CS' : 'TM', + createUe( + app, + { branchOptions: [branchOptions[(i * 3) % 4]] }, + { + code: `XX${`${i}`.padStart(2, '0')}`, + credits: [ + { + category: { + code: i % 3 == 0 ? 'CS' : 'TM', + name: i % 3 == 0 ? 'CS' : 'TM', + }, + credits: 6, }, - credits: 6, - }, - ], - openSemesters: [semesters[i % 2]], - branchOption: [branchOptions[(i * 3) % 4]], - }), + ], + openSemesters: [semesters[i % 2]], + }, + ), ); - const ueWithRating = createUe(app, { - code: `XX30`, - openSemesters: semesters, - branchOption: [branchOptions[0]], - }); + const ueWithRating = createUe( + app, + { branchOptions: [branchOptions[0]] }, + { + code: `XX30`, + openSemesters: semesters, + }, + ); const criterion = createCriterion(app); createUeSubscription(app, { user, ue: ueWithRating, semester: semesters[0] }); createUeSubscription(app, { user: user2, ue: ueWithRating, semester: semesters[0] }); @@ -71,7 +83,11 @@ const GetE2ESpec = e2eSuite('GET /ue/{ueCode}', (app) => { }); it('should return the UE XX01', () => { - return pactum.spec().withBearerToken(user.token).get('/ue/XX01').expectUe(ues[1]); + return pactum.spec().withBearerToken(user.token).get('/ue/XX01').expectUe(ues[1], []); + }); + + it('should return the UE XX01 without ratings', () => { + return pactum.spec().withBearerToken(user3.token).get('/ue/XX01').expectUe(ues[1]); }); it('should return the UE XX30 with rating', () => { @@ -82,7 +98,15 @@ const GetE2ESpec = e2eSuite('GET /ue/{ueCode}', (app) => { .expectUe(ueWithRating, [ { criterionId: criterion.id, - value: computeRate([rate2 as Required, rate1 as Required]), + value: app() + .get(UeController) + .computeRate( + [ + { ...(rate2 as Required), ueofCode: ueWithRating.ueofCode }, + { ...(rate1 as Required), ueofCode: ueWithRating.ueofCode }, + ], + ueWithRating.ueofCode, + ), }, ]); }); diff --git a/test/e2e/ue/put-rate.e2e-spec.ts b/test/e2e/ue/put-rate.e2e-spec.ts index a7c085a..1867526 100644 --- a/test/e2e/ue/put-rate.e2e-spec.ts +++ b/test/e2e/ue/put-rate.e2e-spec.ts @@ -19,7 +19,7 @@ const PutRate = e2eSuite('PUT /ue/{ueCode}/rate', (app) => { const semester = createSemester(app); const branch = createBranch(app); const branchOption = createBranchOption(app, { branch }); - const ue = createUe(app, { openSemesters: [semester], branchOption: [branchOption] }); + const ue = createUe(app, { branchOptions: [branchOption] }, { openSemesters: [semester] }); const criterion = createCriterion(app); createUeSubscription(app, { user, ue, semester }); diff --git a/test/e2e/ue/search.e2e-spec.ts b/test/e2e/ue/search.e2e-spec.ts index c6c992b..cf4c1a7 100644 --- a/test/e2e/ue/search.e2e-spec.ts +++ b/test/e2e/ue/search.e2e-spec.ts @@ -29,20 +29,23 @@ const SearchE2ESpec = e2eSuite('GET /ue', (app) => { const ues: FakeUe[] = []; for (let i = 0; i < 30; i++) ues.push( - createUe(app, { - code: `XX${`${i}`.padStart(2, '0')}`, - credits: [ - { - category: { - code: i % 3 == 0 ? 'CS' : 'TM', - name: i % 3 == 0 ? 'CS' : 'TM', + createUe( + app, + { branchOptions: [branchOptions[i % 4]] }, + { + code: `XX${`${i}`.padStart(2, '0')}`, + credits: [ + { + category: { + code: i % 3 == 0 ? 'CS' : 'TM', + name: i % 3 == 0 ? 'CS' : 'TM', + }, + credits: 6, }, - credits: 6, - }, - ], - openSemesters: [semesters[i % 2]], - branchOption: [branchOptions[i % 4]], - }), + ], + openSemesters: [semesters[i % 2]], + }, + ), ); it('should return a 400 as semester is in a wrong format', () => { @@ -50,7 +53,7 @@ const SearchE2ESpec = e2eSuite('GET /ue', (app) => { .spec() .withBearerToken(user.token) .get('/ue?q=XX01&availableAtSemester=AP28') - .expectAppError(ERROR_CODE.PARAM_TOO_LONG, 'availableAtSemester'); + .expectAppError(ERROR_CODE.PARAM_INVALID_SIZE, 'availableAtSemester'); }); it('should return a 400 as page is negative', () => { @@ -106,7 +109,9 @@ const SearchE2ESpec = e2eSuite('GET /ue', (app) => { }); it('should return a list of ues filtered by branch option', () => { - const expectedUes = ues.filter((ue) => ue.branchOption.some((branchOption) => branchOption.code === 'T1')); + const expectedUes = ues.filter((ue) => + ue.credits.some((credit) => credit.branchOptions.some((branchOption) => branchOption.code === 'T1')), + ); return pactum .spec() .withBearerToken(user.token) @@ -116,7 +121,9 @@ const SearchE2ESpec = e2eSuite('GET /ue', (app) => { }); it('should return a list of ues filtered by branch', () => { - const expectedUes = ues.filter((ue) => ue.branchOption.some((branchOption) => branchOption.branch.code === 'B1')); + const expectedUes = ues.filter((ue) => + ue.credits.some((credit) => credit.branchOptions.some((branchOption) => branchOption.branch.code === 'B1')), + ); return pactum .spec() .withBearerToken(user.token) diff --git a/test/utils/fakedb.ts b/test/utils/fakedb.ts index 6e13b0c..af7ff46 100644 --- a/test/utils/fakedb.ts +++ b/test/utils/fakedb.ts @@ -16,7 +16,7 @@ import { RawUeCommentReply, RawUeCommentUpvote, RawUeCredit, - RawUeInfo, + RawUeofInfo, RawUeStarCriterion, RawUeStarVote, RawUeWorkTime, @@ -78,12 +78,16 @@ export type FakeAsso = Partial< } >; export type FakeSemester = Partial; -export type FakeUe = Partial> & { +export type FakeUe = Partial> & { + ueofCode?: string; name?: Partial; - credits?: (Partial & { category: RawCreditCategory })[]; + siepId?: number; + credits?: (Partial & { + category: RawCreditCategory; + branchOptions?: Partial[]; + })[]; info?: Partial< - Omit & { - comment: Partial; + Omit & { objectives: Partial; program: Partial; requirements: { code: string }[]; @@ -91,7 +95,6 @@ export type FakeUe = Partial> & { >; workTime?: Partial; openSemesters?: Partial[]; - branchOption?: Partial[]; }; export type FakeUserUeSubscription = Partial; export type FakeUeStarCriterion = Partial; @@ -154,6 +157,7 @@ export interface FakeEntityMap { ue: { entity: FakeUe; params: CreateUeParameters; + deps: { branchOptions: FakeBranchOption[] }; }; userUeSubscription: { entity: FakeUserUeSubscription; @@ -317,7 +321,7 @@ export const createUser = entityFaker( semesterNumber: branch.semesterNumber, semesterCode: branch.semester.code, branchCode: branch.branch.code, - branchOptionId: branch.branchOption.id, + branchOptionId: branch.branchOption.code, })), }, }, @@ -660,16 +664,19 @@ export const createAnnal = entityFaker( semesterId: semester.code, senderId: sender.id, typeId: type.id, - ueId: ue.id, + ueofId: ue.ueofCode, }, }), ); -export type CreateUeParameters = FakeUe; +export type CreateUeParameters = Omit & { + credits: Omit, 'branchOptions'>[]; +}; export const createUe = entityFaker( 'ue', { code: faker.db.ue.code, + siepId: () => faker.datatype.number({ min: 100000, max: 999999 }), name: () => faker.db.translation(faker.name.jobTitle), credits: [ { @@ -689,105 +696,112 @@ export const createUe = entityFaker( td: () => faker.datatype.number({ min: 0, max: 100 }), tp: () => faker.datatype.number({ min: 0, max: 100 }), the: () => faker.datatype.number({ min: 0, max: 100 }), - project: () => faker.datatype.number({ min: 0, max: 100 }), + project: faker.datatype.boolean, internship: () => faker.datatype.number({ min: 0, max: 100 }), }, - branchOption: [], openSemesters: [], }, - async (app, params) => + async (app, { branchOptions }, params) => app() .get(PrismaService) .withDefaultBehaviour.ue.create({ data: { - ...omit(params, 'name', 'credits', 'info', 'workTime', 'inscriptionCode', 'openSemesters'), - name: { + ...omit(params, 'siepId', 'name', 'credits', 'info', 'workTime', 'openSemesters'), + ueofs: { create: { - fr: 'TODO : implement this value', - ...params.name, - }, - }, - inscriptionCode: params.inscriptionCode ?? params.code, - credits: { - create: params.credits.map((credit) => ({ - category: { - connectOrCreate: { - create: credit.category, - where: { code: credit.category.code }, - }, - }, - credits: credit.credits, - })), - }, - info: { - create: { - ...omit(params.info, 'requirements', 'comment', 'objectives', 'program'), - comment: { + code: params.ueofCode || `${params.code}_FR_TRO_U23`, + siepId: params.siepId, + available: true, + name: { create: { fr: 'TODO : implement this value', - ...params.info.comment, + ...params.name, }, }, - objectives: { - create: { - fr: 'TODO : implement this value', - ...params.info.objectives, - }, + credits: { + create: params.credits.map((credit) => ({ + category: { + connectOrCreate: { + create: credit.category, + where: { code: credit.category.code }, + }, + }, + credits: credit.credits, + branchOptions: { + connect: branchOptions.map((branchOption) => ({ + code: branchOption.code, + })), + }, + })), }, - program: { + info: { create: { - fr: 'TODO : implement this value', - ...params.info.program, + ...omit(params.info, 'objectives', 'program'), + objectives: { + create: { + fr: 'TODO : implement this value', + ...params.info.objectives, + }, + }, + program: { + create: { + fr: 'TODO : implement this value', + ...params.info.program, + }, + }, }, }, + workTime: { + create: params.workTime, + }, + openSemester: { + connect: params.openSemesters.map((semester) => ({ + code: semester.code, + })), + }, }, }, - workTime: { - create: params.workTime, - }, - branchOption: { - connect: params.branchOption.map((branchOption) => ({ - id: branchOption.id, - })), - }, - openSemester: { - connect: params.openSemesters.map((semester) => ({ - code: semester.code, - })), - }, }, include: { - name: translationSelect, - info: { + ueofs: { include: { + name: translationSelect, requirements: { select: { code: true, }, }, - comment: translationSelect, - objectives: translationSelect, - program: translationSelect, - }, - }, - workTime: true, - credits: { - include: { - category: true, - }, - }, - openSemester: true, - branchOption: { - include: { - branch: true, + info: { + include: { + objectives: translationSelect, + program: translationSelect, + }, + }, + workTime: true, + credits: { + include: { + category: true, + branchOptions: { + include: { + branch: true, + }, + }, + }, + }, + openSemester: true, }, }, }, }) .then((ue) => ({ - ...omit(ue, 'openSemester', 'ueInfoId', 'nameTranslationId'), - info: omit(ue.info, 'commentTranslationId', 'objectivesTranslationId', 'programTranslationId'), - openSemesters: ue.openSemester, + ...omit(ue, 'ueofs'), + ueofCode: ue.ueofs[0].code, + ...omit(ue.ueofs[0], 'code', 'ueId', 'ueofInfoId', 'openSemester', 'nameTranslationId', 'requirements'), + info: { + ...omit(ue.ueofs[0].info, 'objectivesTranslationId', 'programTranslationId'), + requirements: ue.ueofs[0].requirements, + }, + openSemesters: ue.ueofs[0].openSemester, })), ); @@ -797,15 +811,15 @@ export const createUeSubscription = entityFaker('userUeSubscription', {}, async .get(PrismaService) .userUeSubscription.create({ data: { - ...omit(params, 'semesterId', 'ueId', 'userId'), + ...omit(params, 'semesterId', 'ueofId', 'userId'), semester: { connect: { code: dependencies.semester.code, }, }, - ue: { + ueof: { connect: { - code: dependencies.ue.code, + code: dependencies.ue.ueofCode, }, }, user: { @@ -850,15 +864,15 @@ export const createUeRating = entityFaker( .get(PrismaService) .withDefaultBehaviour.ueStarVote.create({ data: { - ...omit(params, 'criterionId', 'ueId', 'userId'), + ...omit(params, 'criterionId', 'ueofId', 'userId'), criterion: { connect: { id: dependencies.criterion.id, }, }, - ue: { + ueof: { connect: { - code: dependencies.ue.code, + code: dependencies.ue.ueofCode, }, }, user: { @@ -884,12 +898,12 @@ export const createComment = entityFaker( .get(PrismaService) .withDefaultBehaviour.ueComment.create({ data: { - ...omit(params, 'ueId', 'authorId', 'semesterId', 'status'), + ...omit(params, 'ueofId', 'authorId', 'semesterId', 'status'), validatedAt: params.status & CommentStatus.VALIDATED ? new Date() : undefined, deletedAt: params.status & CommentStatus.DELETED ? new Date() : undefined, - ue: { + ueof: { connect: { - code: dependencies.ue.code, + code: dependencies.ue.ueofCode, }, }, author: {