diff --git a/.env.dist b/.env.dist index 96900002..4fb658e7 100644 --- a/.env.dist +++ b/.env.dist @@ -18,6 +18,9 @@ LDAP_USER= LDAP_PWD= ANNAL_UPLOAD_DIR=uploads/exams/ +MEDIA_UPLOAD_DIR=uploads/media +MEDIA_DETACHED_LIFESPAN=1 + CAS_URL=https://cas.utt.fr/cas CAS_SERVICE=http://localhost:8080 diff --git a/.env.test.dist b/.env.test.dist index 0ee7f187..e2409acd 100644 --- a/.env.test.dist +++ b/.env.test.dist @@ -14,6 +14,9 @@ PAGINATION_PAGE_SIZE=20 FAKER_SEED=42 ANNAL_UPLOAD_DIR=uploads/exams/ +MEDIA_UPLOAD_DIR=uploads/media +MEDIA_DETACHED_LIFESPAN=1 + CAS_URL=https://cas.utt.fr/cas CAS_SERVICE=https://etu.utt.fr/login LDAP_URL=ldap://localhost:3002 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 52ebd9c6..907c08ca 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -50,6 +50,31 @@ jobs: - run: pnpm prisma generate - run: pnpm build + docs: + runs-on: self-hosted + strategy: + matrix: + node-version: [22] + pnpm-version: [10] + steps: + - uses: actions/checkout@v5 + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ matrix.pnpm-version }} + - name: Use Node.js + uses: actions/setup-node@v6 + with: + package-manager-cache: false + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + - name: Use Python + uses: actions/setup-python@v6 + with: + python-version: '3.14' + - run: pnpm build:docs:configure + - run: pnpm build:docs + test: runs-on: self-hosted strategy: diff --git a/.gitignore b/.gitignore index e9ace105..c21f40a1 100644 --- a/.gitignore +++ b/.gitignore @@ -111,6 +111,10 @@ yarn.lock docs/_build/ docs/build/ +# Prisma generated files +src/prisma/types/**/*.ts +!src/prisma/types/index.ts + # OLD DATABASE, DO NOT PUSH, IT CONTAINS SENSITIVE DATA migration/etuutt_old/etuutt_old.sql # UE Data diff --git a/docs/conf.py b/docs/conf.py index 97d25c49..1b94680b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,7 @@ # -- Project information ----------------------------------------------------- project = 'EtuUTT' -copyright = '2024, UTT Net Group' +copyright = '2025, UTT Net Group' author = 'UTT Net Group' @@ -52,7 +52,14 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = 'shibuya' +html_theme_options = { + "accent_color": "blue", + "github_url": "https://github.com/ungdev/etu-utt-api", + "announcement": "
Le site étu est toujours en cours de développement : la documentation est en cours d'écriture et peux être incomplète/incorrecte.
", +} +html_favicon = "logo.svg" +html_logo = "logo.svg" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -64,4 +71,5 @@ '.md': 'markdown', } -myst_enable_extensions = ["attrs_inline"] \ No newline at end of file +myst_enable_extensions = ["attrs_inline"] +myst_heading_anchors = 4 \ No newline at end of file diff --git a/docs/doc_developers/api/index.md b/docs/doc_developers/api/index.md index 2950cccd..b1b0ffbb 100644 --- a/docs/doc_developers/api/index.md +++ b/docs/doc_developers/api/index.md @@ -1,4 +1,4 @@ -# Documentation développeurs - API +# API Cette documentation s'adresse aux développeurs de l'API de EtuUTT. Elle traite des aspects techniques la concernant : outils utilisés, outils développés, choix faits, ... @@ -10,6 +10,11 @@ setup.md nestjs.md conventions.md test.md +documentation.md +errors.md +permissions.md +lexical.md ues.md timetables.md +scripts.md ``` diff --git a/docs/doc_developers/api/lexical.md b/docs/doc_developers/api/lexical.md new file mode 100644 index 00000000..a4ce5b3d --- /dev/null +++ b/docs/doc_developers/api/lexical.md @@ -0,0 +1,88 @@ +# Texte formatable + +```{danger} +*Le texte formatable est un **sujet de travail actuel**. Son implémentation est susceptible de changer.* \ +Par ailleurs, il est possible que cette fonctionnalité soit séparée dans un package nodejs indépendant. +``` + +A certains endroits du site étu, les utilisateurs pourront formatter du texte. Nous avons décidé de nous baser sur une bibliothèque, [lexical](https://lexical.dev) ([github](https://github.com/facebook/lexical)). Bien que l'utilisateur puisse envoyer du contenu formatté sur à peu près n'importe quel champ texte de l'api (à condition de respecter la limite de caractères), il n'y a que quelques champs qui supportent réellement le texte formatté. + +```{warning} +Les champs qui ne supportent pas le texte formatté acceptent **pour le moment** des inputs formattés. Cependant, ces champs ne seront pas traités comme telles par les applications front-end (comme le front du site étu). Cela peut donner lieu à un affichage considéré comme buggé si la feature est mal utilisée par certaines implémentations front-end ! +``` + +## Abbréviations dans ce document + +Nous utiliserons dans ce documents les abbréviations/anglicismes suivantes : + +- RTE: Rich Text Editor, l'éditeur de texte dans lequel l'utilisateur peut formater du texte +- Renderer: côté serveur, la fonction qui transforme du contenu lexical en html +- Document Object Model (DOM): la structure d'un document, généralement HTML. On l'utilisera ici pour parler de tout ce qui est relatif à l'affichage du texte formatable. + +## Les bundles + +Un bundle est la définition de l'ensemble des contenus supportés par une zone de texte formatable. Il contient des [nodes](#node) et, pour le front, des [plugins](#plugin) et des [composants de toolbar](#composant-de-toolbar). +La définition d'un bundle permet de configurer plusieurs RTE ou Renderers de manière identique. + +Détaillons maintenant les différents éléments contenu dans un bundle : + +### Node + +Une node est une partie du texte ou un élément visuel que l'utilisateur peut ajouter à son texte. Il peut s'agir par exemple d'images, d'émojis customs, ou de texte avec un fond coloré. +Pour créer de nouvelles capacités/de nouveaux éléments dans le texte formatté, la première étape est de créer une `class` qui hérite de `ElementNode`, `TextNode` ou `DecoratorNode`. Pour voir les méthodes à implémenter, regarde [la doc de lexical](https://lexical.dev/docs/concepts/nodes#creating-custom-nodes). Comme indiqué plus bas dans la doc, tu peux utiliser [`$config` et ne pas implémenter les 3 fonctions statiques](https://lexical.dev/docs/concepts/nodes#extending-elementnode-with-config). + +```{tip} +Seule les `DecoratorNode` pourront être rendues avec une ReactNode côté front (cf. `DecoratorNode#decorate`). Si tu n'as pas envie d'écrire des opérations DOM, cela peut être une bonne solution 😉 +``` + +Lorsque tu appliques des classes à des éléments, fais bien attention à prendre celles du thème de l'éditeur, `editor.theme[className]`. Tu pourrais sinon oublier de les implémenter de l'autre côté (serveur/client) et le rendu serait alors différent ! + +Si tu souhaites remplacer une node déjà définie, tu peux enregistrer des [remplacements](https://lexical.dev/docs/concepts/node-replacement). Cela t'évitera de devoir copier-coller tout son code, et à chaque fois qu'une node remplacée sera créée, elle sera transformée en ta nouvelle node à l'aide de la fonction que tu auras définie ! + +### Plugin + +Les plugins n'existent que côté front-end. Ce sont eux qui vont ajouter de la logique, tu vas pouvoir: + +- écouter des [évènements](https://lexical.dev/docs/concepts/commands), à l'aide de `editor.registerCommand()` +- enregistrer des [transformers](https://lexical.dev/docs/concepts/transforms) avec `editor.registerNodeTransform()` +- en react, utiliser `useEffect` +- rendre un élément supplémentaire, un overlay par exemple + +```{admonition} TLDR +:class: tip +Un transformer, c'est du code qui va te permettre de transformer du contenu dans le RTE au fur et à mesure qu'il est ajouté. Par exemple, tu peux transformer automatiquement `:joy:` en l'émoji correspondant, 😂. +``` + +### Composant de toolbar + +Ce qui permettra à l'utilisateur d'intéragir avec tes nodes depuis une interface. + +A l'heure actuelle, ces composants n'existent pas encore en tant que tel et font partie du composant `ToolbarPlugin`. Leur future séparation permettra d'ajouter facilement des composants (boutons, etc) custom dans cette toolbar. + +## Côté serveur + +Bien que le serveur n'ait pas à gérer l'édition en temps réel, il doit pouvoir effectuer quelques opérations sur le contenu généré par l'utilisateur. Cela inclut la validation du contenu lexical et l'export en HTML (pour pouvoir l'utiliser dans des emails par exemple). + +```{admonition} Structure Lexical +La structure envoyée entre le client est le front est un JSON (créé avec `LexicalNode#exportJSON`). Il contient les nodes imbriquées les unes dans les autres. +``` + +### La validation + +La validation vérifie que le contenu fourni utilisateur a bien une structure comprise par le serveur. Cela vérifie : + +- que c'est bien du JSON +- que l'éditeur lexical le comprend +- qu'il n'y a pas de node absente du bundle +- qu'il n'y a pas de propriétés inconnues sur les nodes + +```{attention} +Les propriétés des nodes doivent apparaitre dans le même sens lors de l'exportJSON côté front et côté serveur. +``` + +### Le rendu + +Le rendu permet au serveur de transformer du contenu lexical en html. Il faut faire attention à deux points ici : + +- les méthodes `DecoratorNode#decorate` doivent être enlevées et le contenu de la node doit être traduit en instructions DOM dans `DecoratorNode#createDOM` +- les styles appliqués sur le front doivent être réappliqués sur le DOM produit sur l'API. Cela peut nécessiter des modifications structurelles dans l'HTML généré. En cas de besoin, il est possible d'ajouter des conditions spécifiques dans `NodeStyleInjector.ts` diff --git a/docs/doc_developers/api/nestjs.md b/docs/doc_developers/api/nestjs.md index 345f35d7..3abf8333 100644 --- a/docs/doc_developers/api/nestjs.md +++ b/docs/doc_developers/api/nestjs.md @@ -228,7 +228,7 @@ export class DummyModule {} ``` ```{tip} -L'API de EtuUTT utilise des guards personnalisés, ils sont listés [ici](#outils-specifiques-de-etuutt). +L'API de EtuUTT utilise des guards personnalisés, ils sont listés [ici](#outils-spécifiques-du-site-étu). ``` ### Les interceptors [_(docs)_](https://docs.nestjs.com/interceptors) @@ -292,7 +292,7 @@ Voici une illustration qui permet de récapituler les différentes étapes dans ### La gestion des erreurs -Nous avons implémenté des messages d'erreurs customisés, voir la page sur [la gestion des erreurs](). +Nous avons implémenté des messages d'erreurs customisés, voir la page sur [la gestion des erreurs](errors.md). ### L'authentification nécessaire par défaut diff --git a/docs/doc_developers/api/setup.md b/docs/doc_developers/api/setup.md index 3c8025b1..82112afc 100644 --- a/docs/doc_developers/api/setup.md +++ b/docs/doc_developers/api/setup.md @@ -171,14 +171,10 @@ Les tests sont tous lancés. Au bout de quelques secondes / minutes, tous les te Pour cela, vous devez avoir Python3 installé. -Il faut commencer par installer les dépendances : - ```bash -# Pour les commandes pip, il est possible d'utiliser python -m pip (ou python3 -m pip) à la place de pip. -cd docs -pip install --upgrade pip setuptools sphinx readthedocs-sphinx-ext -pip install -r docs/requirements.txt -python -m sphinx -T -b html -d _build/doctrees -D language=fr . build/html +# Pour la première commande, il faut la faire uniquement la première fois, elle va installer les dépendances python +pnpm build:docs:configure +pnpm build:docs ``` Le résultat du build se situe alors dans `docs/build/html`. Le fichier racine est `index.html`. Le résultat de la diff --git a/docs/doc_developers/front/index.md b/docs/doc_developers/front/index.md index 3b908059..424d5fee 100644 --- a/docs/doc_developers/front/index.md +++ b/docs/doc_developers/front/index.md @@ -1,4 +1,4 @@ -# Documentation développeurs - Site web +# Site web Cette documentation s'adresse aux développeurs du site web de EtuUTT. Elle traite des aspects techniques le concernant : outils utilisés, outils développés, choix faits, ... diff --git a/docs/doc_developers/index.md b/docs/doc_developers/index.md index bf45e07e..bc9bc5fc 100644 --- a/docs/doc_developers/index.md +++ b/docs/doc_developers/index.md @@ -1,4 +1,4 @@ -# Documentation développeurs +# Développeurs Cette documentation s'adresse aux développeurs de EtuUTT. Elle traite des aspects techniques de l'API, de l'application mobile et du site web : outils utilisés, outils développés, choix faits, ... diff --git a/docs/doc_developers/mobile_app/index.md b/docs/doc_developers/mobile_app/index.md index ad04e552..d199d803 100644 --- a/docs/doc_developers/mobile_app/index.md +++ b/docs/doc_developers/mobile_app/index.md @@ -1,4 +1,4 @@ -# Documentation EtuUTT - Application mobile +# Application mobile Cette documentation s'adresse aux développeurs de l'appli MyUTT. Elle traite des aspects techniques la concernant : outils utilisés, outils développés, choix faits, ... diff --git a/docs/logo.svg b/docs/logo.svg new file mode 100644 index 00000000..19aea1ff --- /dev/null +++ b/docs/logo.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index c00cdf64..268bb648 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ myst-parser sphinx -sphinx-rtd-theme \ No newline at end of file +shibuya diff --git a/migration/etuutt_old/make-migration.ts b/migration/etuutt_old/make-migration.ts index 28a81590..f99140c6 100644 --- a/migration/etuutt_old/make-migration.ts +++ b/migration/etuutt_old/make-migration.ts @@ -1,4 +1,5 @@ -import { PrismaClient as _PrismaClient } from '@prisma/client'; +import { PrismaClient as _PrismaClient } from '../../src/prisma/types'; +import { PrismaMariaDb } from '@prisma/adapter-mariadb'; import { createConnection } from 'mysql'; import { cleanDb } from '../../test/utils/test_utils'; import { findLegacyUeofName, migrateUEs } from './modules/ue'; @@ -34,7 +35,7 @@ export async function getOperationResults(operations: MayBePromise=0.10.0'} - - '@ampproject/remapping@2.2.1': - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} - engines: {node: '>=6.0.0'} - - '@angular-devkit/core@19.2.6': - resolution: {integrity: sha512-WFgiYhrDMq83UNaGRAneIM7CYYdBozD+yYA9BjoU8AgBLKtrvn6S8ZcjKAk5heoHtY/u8pEb0mwDTz9gxFmJZQ==} + '@angular-devkit/core@19.2.15': + resolution: {integrity: sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: chokidar: ^4.0.0 @@ -209,8 +225,8 @@ packages: chokidar: optional: true - '@angular-devkit/core@19.2.8': - resolution: {integrity: sha512-kcxUHKf5Hi98r4gAvMP3ntJV8wuQ3/i6wuU9RcMP0UKUt2Rer5Ryis3MPqT92jvVVwg6lhrLIhXsFuWJMiYjXQ==} + '@angular-devkit/core@19.2.17': + resolution: {integrity: sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} peerDependencies: chokidar: ^4.0.0 @@ -218,99 +234,79 @@ packages: chokidar: optional: true - '@angular-devkit/schematics-cli@19.2.8': - resolution: {integrity: sha512-RFnlyu4Ld8I4xvu/eqrhjbQ6kQTr27w79omMiTbQcQZvP3E6oUyZdBjobyih4Np+1VVQrbdEeNz76daP2iUDig==} + '@angular-devkit/schematics-cli@19.2.15': + resolution: {integrity: sha512-1ESFmFGMpGQmalDB3t2EtmWDGv6gOFYBMxmHO2f1KI/UDl8UmZnCGL4mD3EWo8Hv0YIsZ9wOH9Q7ZHNYjeSpzg==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true - '@angular-devkit/schematics@19.2.6': - resolution: {integrity: sha512-YTAxNnT++5eflx19OUHmOWu597/TbTel+QARiZCv1xQw99+X8DCKKOUXtqBRd53CAHlREDI33Rn/JLY3NYgMLQ==} + '@angular-devkit/schematics@19.2.15': + resolution: {integrity: sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@angular-devkit/schematics@19.2.8': - resolution: {integrity: sha512-QsmFuYdAyeCyg9WF/AJBhFXDUfCwmDFTEbsv5t5KPSP6slhk0GoLNZApniiFytU2siRlSxVNpve2uATyYuAYkQ==} + '@angular-devkit/schematics@19.2.17': + resolution: {integrity: sha512-ADfbaBsrG8mBF6Mfs+crKA/2ykB8AJI50Cv9tKmZfwcUcyAdmTr+vVvhsBCfvUAEokigSsgqgpYxfkJVxhJYeg==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.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.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.23.5': - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} - '@babel/core@7.23.6': - resolution: {integrity: sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==} + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.23.6': - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.22.15': - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.23.3': - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.22.5': - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-simple-access@7.22.5': - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.23.4': - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} 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.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.23.6': - resolution: {integrity: sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==} + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.23.4': - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.23.6': - resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} engines: {node: '>=6.0.0'} hasBin: true @@ -329,6 +325,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-meta@7.10.4': resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: @@ -339,8 +347,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.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -375,229 +383,280 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-top-level-await@7.14.5': resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} 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.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/template@7.22.15': - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.23.6': - resolution: {integrity: sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.23.6': - resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@borewit/text-codec@0.1.1': + resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} + '@commander-js/extra-typings@13.1.0': + resolution: {integrity: sha512-q5P52BYb1hwVWE6dtID7VvuJWrlfbCv4klj7BjUUOqMz4jbSZD4C9fJ9lRjL2jnBGTg+gDDlaXN51rkWcLk4fg==} + peerDependencies: + commander: ~13.1.0 + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@emnapi/runtime@1.3.1': - resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@emnapi/core@1.6.0': + resolution: {integrity: sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==} - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@emnapi/runtime@1.7.0': + resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==} - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.20.0': - resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.2.2': - resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.14.0': - resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.27.0': - resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} + '@eslint/js@9.39.1': + resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.1': - resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@exodus/schemasafe@1.3.0': resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} - '@faker-js/faker@9.8.0': - resolution: {integrity: sha512-U9wpuSrJC93jZBxx/Qq2wPjCuYISBueyVUGK7qqdmj7r/nxaxwW8AQDCLeRO7wZnjj94sh3p246cAYjUKuqgfg==} + '@faker-js/faker@9.9.0': + resolution: {integrity: sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==} engines: {node: '>=18.0.0', npm: '>=9.0.0'} - '@fast-csv/parse@5.0.2': - resolution: {integrity: sha512-gMu1Btmm99TP+wc0tZnlH30E/F1Gw1Tah3oMDBHNPe9W8S68ixVHjt89Wg5lh7d9RuQMtwN+sGl5kxR891+fzw==} + '@fast-csv/parse@5.0.5': + resolution: {integrity: sha512-M0IbaXZDbxfOnpVE5Kps/a6FGlILLhtLsvWd9qNH3d2TxNnpbNkFf3KD26OmJX6MHq7PdQAl5htStDwnuwHx6w==} '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@inquirer/checkbox@4.1.8': - resolution: {integrity: sha512-d/QAsnwuHX2OPolxvYcgSj7A9DO9H6gVOy2DvBTx+P2LH2iRTo/RSGV3iwCzW024nP9hw98KIuDmdyhZQj1UQg==} + '@inquirer/ansi@1.0.1': + resolution: {integrity: sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==} + engines: {node: '>=18'} + + '@inquirer/checkbox@4.3.0': + resolution: {integrity: sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@5.1.19': + resolution: {integrity: sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -605,8 +664,8 @@ packages: '@types/node': optional: true - '@inquirer/confirm@5.1.12': - resolution: {integrity: sha512-dpq+ielV9/bqgXRUbNH//KsY6WEw9DrGPmipkpmgC1Y46cwuBTNx7PXFWTjc3MQ+urcc0QxoVHcMI0FW4Ok0hg==} + '@inquirer/core@10.3.0': + resolution: {integrity: sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -614,8 +673,8 @@ packages: '@types/node': optional: true - '@inquirer/core@10.1.13': - resolution: {integrity: sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==} + '@inquirer/editor@4.2.21': + resolution: {integrity: sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -623,8 +682,8 @@ packages: '@types/node': optional: true - '@inquirer/editor@4.2.13': - resolution: {integrity: sha512-WbicD9SUQt/K8O5Vyk9iC2ojq5RHoCLK6itpp2fHsWe44VxxcA9z3GTWlvjSTGmMQpZr+lbVmrxdHcumJoLbMA==} + '@inquirer/expand@4.0.21': + resolution: {integrity: sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -632,8 +691,8 @@ packages: '@types/node': optional: true - '@inquirer/expand@4.0.15': - resolution: {integrity: sha512-4Y+pbr/U9Qcvf+N/goHzPEXiHH8680lM3Dr3Y9h9FFw4gHS+zVpbj8LfbKWIb/jayIB4aSO4pWiBTrBYWkvi5A==} + '@inquirer/external-editor@1.0.2': + resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -641,12 +700,12 @@ packages: '@types/node': optional: true - '@inquirer/figures@1.0.12': - resolution: {integrity: sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==} + '@inquirer/figures@1.0.14': + resolution: {integrity: sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==} engines: {node: '>=18'} - '@inquirer/input@4.1.12': - resolution: {integrity: sha512-xJ6PFZpDjC+tC1P8ImGprgcsrzQRsUh9aH3IZixm1lAZFK49UGHxM3ltFfuInN2kPYNfyoPRh+tU4ftsjPLKqQ==} + '@inquirer/input@4.2.5': + resolution: {integrity: sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -654,8 +713,8 @@ packages: '@types/node': optional: true - '@inquirer/number@3.0.15': - resolution: {integrity: sha512-xWg+iYfqdhRiM55MvqiTCleHzszpoigUpN5+t1OMcRkJrUrw7va3AzXaxvS+Ak7Gny0j2mFSTv2JJj8sMtbV2g==} + '@inquirer/number@3.0.21': + resolution: {integrity: sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -663,8 +722,8 @@ packages: '@types/node': optional: true - '@inquirer/password@4.0.15': - resolution: {integrity: sha512-75CT2p43DGEnfGTaqFpbDC2p2EEMrq0S+IRrf9iJvYreMy5mAWj087+mdKyLHapUEPLjN10mNvABpGbk8Wdraw==} + '@inquirer/password@4.0.21': + resolution: {integrity: sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -681,8 +740,8 @@ packages: '@types/node': optional: true - '@inquirer/prompts@7.4.1': - resolution: {integrity: sha512-UlmM5FVOZF0gpoe1PT/jN4vk8JmpIWBlMvTL8M+hlvPmzN89K6z03+IFmyeu/oFCenwdwHDr2gky7nIGSEVvlA==} + '@inquirer/prompts@7.8.0': + resolution: {integrity: sha512-JHwGbQ6wjf1dxxnalDYpZwZxUEosT+6CPGD9Zh4sm9WXdtUp9XODCQD3NjSTmu+0OAyxWXNOqf0spjIymJa2Tw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -690,8 +749,8 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@4.1.3': - resolution: {integrity: sha512-7XrV//6kwYumNDSsvJIPeAqa8+p7GJh7H5kRuxirct2cgOcSWwwNGoXDRgpNFbY/MG2vQ4ccIWCi8+IXXyFMZA==} + '@inquirer/rawlist@4.1.9': + resolution: {integrity: sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -699,8 +758,8 @@ packages: '@types/node': optional: true - '@inquirer/search@3.0.15': - resolution: {integrity: sha512-YBMwPxYBrADqyvP4nNItpwkBnGGglAvCLVW8u4pRmmvOsHUtCAUIMbUrLX5B3tFL1/WsLGdQ2HNzkqswMs5Uaw==} + '@inquirer/search@3.2.0': + resolution: {integrity: sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -708,8 +767,8 @@ packages: '@types/node': optional: true - '@inquirer/select@4.2.3': - resolution: {integrity: sha512-OAGhXU0Cvh0PhLz9xTF/kx6g6x+sP+PcyTiLvCrewI99P3BBeexD+VbuwkNDvqGkk3y2h5ZiWLeRP7BFlhkUDg==} + '@inquirer/select@4.4.0': + resolution: {integrity: sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -717,8 +776,8 @@ packages: '@types/node': optional: true - '@inquirer/type@3.0.7': - resolution: {integrity: sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==} + '@inquirer/type@3.0.9': + resolution: {integrity: sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -726,6 +785,14 @@ packages: '@types/node': optional: true + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -738,99 +805,153 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/console@30.2.0': + resolution: {integrity: sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/core@30.2.0': + resolution: {integrity: sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/diff-sequences@30.0.1': + resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/environment@30.2.0': + resolution: {integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/expect-utils@30.2.0': + resolution: {integrity: sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect@30.2.0': + resolution: {integrity: sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@30.2.0': + resolution: {integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/get-type@30.1.0': + resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/globals@30.2.0': + resolution: {integrity: sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/pattern@30.0.1': + resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/reporters@30.2.0': + resolution: {integrity: sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@30.0.5': + resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/snapshot-utils@30.2.0': + resolution: {integrity: sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/source-map@30.0.1': + resolution: {integrity: sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-result@30.2.0': + resolution: {integrity: sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-sequencer@30.2.0': + resolution: {integrity: sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/transform@30.2.0': + resolution: {integrity: sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} + '@jest/types@30.2.0': + resolution: {integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} '@jridgewell/resolve-uri@3.1.1': resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/source-map@0.3.5': - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@lexical/clipboard@0.38.2': + resolution: {integrity: sha512-dDShUplCu8/o6BB9ousr3uFZ9bltR+HtleF/Tl8FXFNPpZ4AXhbLKUoJuucRuIr+zqT7RxEv/3M6pk/HEoE6NQ==} + + '@lexical/code@0.38.2': + resolution: {integrity: sha512-wpqgbmPsfi/+8SYP0zI2kml09fGPRhzO5litR9DIbbSGvcbawMbRNcKLO81DaTbsJRnBJiQvbBBBJAwZKRqgBw==} + + '@lexical/dragon@0.38.2': + resolution: {integrity: sha512-riOhgo+l4oN50RnLGhcqeUokVlMZRc+NDrxRNs2lyKSUdC4vAhAmAVUHDqYPyb4K4ZSw4ebZ3j8hI2zO4O3BbA==} + + '@lexical/extension@0.38.2': + resolution: {integrity: sha512-qbUNxEVjAC0kxp7hEMTzktj0/51SyJoIJWK6Gm790b4yNBq82fEPkksfuLkRg9VQUteD0RT1Nkjy8pho8nNamw==} + + '@lexical/headless@0.38.2': + resolution: {integrity: sha512-HFlQrw1pSSia3hGHz/OnUBAVMAGDBLSIJrqiHTst/LhDWzY5Um6PZ5Yc5DhTOtWaOp89d/Gl1SPKj935akVNZQ==} + + '@lexical/html@0.38.2': + resolution: {integrity: sha512-pC5AV+07bmHistRwgG3NJzBMlIzSdxYO6rJU4eBNzyR4becdiLsI4iuv+aY7PhfSv+SCs7QJ9oc4i5caq48Pkg==} + + '@lexical/link@0.38.2': + resolution: {integrity: sha512-UOKTyYqrdCR9+7GmH6ZVqJTmqYefKGMUHMGljyGks+OjOGZAQs78S1QgcPEqltDy+SSdPSYK7wAo6gjxZfEq9g==} + + '@lexical/list@0.38.2': + resolution: {integrity: sha512-OQm9TzatlMrDZGxMxbozZEHzMJhKxAbH1TOnOGyFfzpfjbnFK2y8oLeVsfQZfZRmiqQS4Qc/rpFnRP2Ax5dsbA==} + + '@lexical/rich-text@0.38.2': + resolution: {integrity: sha512-eFjeOT7YnDZYpty7Zlwlct0UxUSaYu53uLYG+Prs3NoKzsfEK7e7nYsy/BbQFfk5HoM1pYuYxFR2iIX62+YHGw==} + + '@lexical/selection@0.38.2': + resolution: {integrity: sha512-eMFiWlBH6bEX9U9sMJ6PXPxVXTrihQfFeiIlWLuTpEIDF2HRz7Uo1KFRC/yN6q0DQaj7d9NZYA6Mei5DoQuz5w==} + + '@lexical/table@0.38.2': + resolution: {integrity: sha512-uu0i7yz0nbClmHOO5ZFsinRJE6vQnFz2YPblYHAlNigiBedhqMwSv5bedrzDq8nTTHwych3mC63tcyKIrM+I1g==} + + '@lexical/utils@0.38.2': + resolution: {integrity: sha512-y+3rw15r4oAWIEXicUdNjfk8018dbKl7dWHqGHVEtqzAYefnEYdfD2FJ5KOTXfeoYfxi8yOW7FvzS4NZDi8Bfw==} + '@lukeed/csprng@1.1.0': resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} engines: {node: '>=8'} @@ -838,19 +959,22 @@ packages: '@microsoft/tsdoc@0.15.1': resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==} - '@mswjs/interceptors@0.38.6': - resolution: {integrity: sha512-qFlpmObPqeUs4u3oFYv/OM/xyX+pNa5TRAjqjvMhbGYlyMhzSrE5UfncL2rUcEeVfD9Gebgff73hPwqcOwJQNA==} + '@mswjs/interceptors@0.39.8': + resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} engines: {node: '>=18'} - '@nestjs/axios@4.0.0': - resolution: {integrity: sha512-1cB+Jyltu/uUPNQrpUimRHEQHrnQrpLzVj6dU3dgn6iDDDdahr10TgHFGTmw5VuJ9GzKZsCLDL78VSwJAs/9JQ==} + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@nestjs/axios@4.0.1': + resolution: {integrity: sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==} peerDependencies: '@nestjs/common': ^10.0.0 || ^11.0.0 axios: ^1.3.1 rxjs: ^7.0.0 - '@nestjs/cli@11.0.7': - resolution: {integrity: sha512-svrP8j1R0/lQVJ8ZI3BlDtuZxmkvVJokUJSB04sr6uibunk2wHeVDDVLZvYBUorCdGU/RHJl1IufhqUBM91vAQ==} + '@nestjs/cli@11.0.10': + resolution: {integrity: sha512-4waDT0yGWANg0pKz4E47+nUrqIJv/UqrZ5wLPkCqc7oMGRMWKAaw1NDZ9rKsaqhqvxb2LfI5+uXOWr4yi94DOQ==} engines: {node: '>= 20.11'} hasBin: true peerDependencies: @@ -862,8 +986,8 @@ packages: '@swc/core': optional: true - '@nestjs/common@11.1.2': - resolution: {integrity: sha512-cHh4OPH44PjaHM93D1jgE1HO/B7XTZVRDxy/cPuGgyMEA4p2zXO+qqcOgTMC5FYcp7dX9jLeCjXAU0ToFAnODw==} + '@nestjs/common@11.1.8': + resolution: {integrity: sha512-bbsOqwld/GdBfiRNc4nnjyWWENDEicq4SH+R5AuYatvf++vf1x5JIsHB1i1KtfZMD3eRte0D4K9WXuAYil6XAg==} peerDependencies: class-transformer: '>=0.4.1' class-validator: '>=0.13.2' @@ -881,8 +1005,8 @@ packages: '@nestjs/common': ^10.0.0 || ^11.0.0 rxjs: ^7.1.0 - '@nestjs/core@11.1.2': - resolution: {integrity: sha512-QRuyxwu0BjNfmmmunsw1ylX7RSyfDQHt+xD+tKncdtgiMOOzAu+LA1gB4WoZnw4frQkk+qZbhEbM61cIjOxD3w==} + '@nestjs/core@11.1.8': + resolution: {integrity: sha512-7riWfmTmMhCJHZ5ZiaG+crj4t85IPCq/wLRuOUSigBYyFT2JZj0lVHtAdf4Davp9ouNI8GINBDt9h9b5Gz9nTw==} engines: {node: '>= 20'} peerDependencies: '@nestjs/common': ^11.0.0 @@ -899,8 +1023,8 @@ packages: '@nestjs/websockets': optional: true - '@nestjs/jwt@11.0.0': - resolution: {integrity: sha512-v7YRsW3Xi8HNTsO+jeHSEEqelX37TVWgwt+BcxtkG/OfXJEOs6GZdbdza200d6KqId1pJQZ6UPj1F0M6E+mxaA==} + '@nestjs/jwt@11.0.1': + resolution: {integrity: sha512-HXSsc7SAnCnjA98TsZqrE7trGtHDnYXWp4Ffy6LwSmck1QvbGYdMzBquXofX5l6tIRpeY4Qidl2Ti2CVG77Pdw==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 @@ -923,19 +1047,19 @@ packages: '@nestjs/common': ^10.0.0 || ^11.0.0 passport: ^0.5.0 || ^0.6.0 || ^0.7.0 - '@nestjs/platform-express@11.1.2': - resolution: {integrity: sha512-GlNwOT4htRp8RpZ+TpqGtSHwGKw/abdxxBRse40XE2SWs5ikaoujr9Yd+5sJWDNXB4QTftwb+FplXhyk1Ra+4A==} + '@nestjs/platform-express@11.1.8': + resolution: {integrity: sha512-rL6pZH9BW7BnL5X2eWbJMtt86uloAKjFgyY5+L2UkizgfEp7rgAs0+Z1z0BcW2Pgu5+q8O7RKPNyHJ/9ZNz/ZQ==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 - '@nestjs/schematics@11.0.5': - resolution: {integrity: sha512-T50SCNyqCZ/fDssaOD7meBKLZ87ebRLaJqZTJPvJKjlib1VYhMOCwXYsr7bjMPmuPgiQHOwvppz77xN/m6GM7A==} + '@nestjs/schematics@11.0.9': + resolution: {integrity: sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==} peerDependencies: typescript: '>=4.8.2' - '@nestjs/swagger@11.2.0': - resolution: {integrity: sha512-5wolt8GmpNcrQv34tIPUtPoV1EeFbCetm40Ij3+M0FNNnf2RJ3FyWfuQvI8SBlcJyfaounYVTKzKHreFXsUyOg==} + '@nestjs/swagger@11.2.1': + resolution: {integrity: sha512-1MS7xf0pzc1mofG53xrrtrurnziafPUHkqzRm4YUVPA/egeiMaSerQBD/feiAeQ2BnX0WiLsTX4HQFO0icvOjQ==} peerDependencies: '@fastify/static': ^8.0.0 '@nestjs/common': ^11.0.1 @@ -951,8 +1075,8 @@ packages: class-validator: optional: true - '@nestjs/testing@11.1.2': - resolution: {integrity: sha512-BQxVKUVW6gzEbbHAvmg5RgcP3s++pRgTCmsgaDF/DtcLRUeKi8SjAdqzLm14xbkMeibxOf3fNqM2iwqUKj8ffw==} + '@nestjs/testing@11.1.8': + resolution: {integrity: sha512-E6K+0UTKztcPxJzLnQa7S34lFjZbrj3Z1r7c5y5WDrL1m5HD1H4AeyBhicHgdaFmxjLAva2bq0sYKy/S7cdeYA==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -996,15 +1120,25 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@pkgr/core@0.2.4': - resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} '@polka/url@0.5.0': resolution: {integrity: sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==} - '@prisma/client@6.8.2': - resolution: {integrity: sha512-5II+vbyzv4si6Yunwgkj0qT/iY0zyspttoDrL3R4BYgLdp42/d2C8xdi9vqkrYtKt9H32oFIukvyw3Koz5JoDg==} + '@preact/signals-core@1.12.1': + resolution: {integrity: sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA==} + + '@prisma/adapter-mariadb@6.19.0': + resolution: {integrity: sha512-Rvp/DipkVgg79fvWxRJ/G0C7QactfyLub1PNeRyotiwDrC3UGMUEpsb0uTaRU6Ji9PmLapcy21Lr0X0QX2X+3w==} + + '@prisma/client@6.19.0': + resolution: {integrity: sha512-QXFT+N/bva/QI2qoXmjBzL7D6aliPffIwP+81AdTGq0FXDoLxLkWivGMawG8iM5B9BKfxLIXxfWWAF6wbuJU6g==} engines: {node: '>=18.18'} peerDependencies: prisma: '*' @@ -1015,35 +1149,41 @@ packages: typescript: optional: true - '@prisma/config@6.8.2': - resolution: {integrity: sha512-ZJY1fF4qRBPdLQ/60wxNtX+eu89c3AkYEcP7L3jkp0IPXCNphCYxikTg55kPJLDOG6P0X+QG5tCv6CmsBRZWFQ==} + '@prisma/config@6.19.0': + resolution: {integrity: sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg==} + + '@prisma/debug@6.19.0': + resolution: {integrity: sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==} - '@prisma/debug@6.8.2': - resolution: {integrity: sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==} + '@prisma/driver-adapter-utils@6.19.0': + resolution: {integrity: sha512-VAC/wFebV569Jk7iEqzLxekM2A5toKYAr6cPM2KWVHiRHgyjsh/IHf++Xo67q8uor/JxY8mwOuyQyuxkstSf5w==} - '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': - resolution: {integrity: sha512-Rkik9lMyHpFNGaLpPF3H5q5TQTkm/aE7DsGM5m92FZTvWQsvmi6Va8On3pWvqLHOt5aPUvFb/FeZTmphI4CPiQ==} + '@prisma/engines-version@6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773': + resolution: {integrity: sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==} - '@prisma/engines@6.8.2': - resolution: {integrity: sha512-XqAJ//LXjqYRQ1RRabs79KOY4+v6gZOGzbcwDQl0D6n9WBKjV7qdrbd042CwSK0v0lM9MSHsbcFnU2Yn7z8Zlw==} + '@prisma/engines@6.19.0': + resolution: {integrity: sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw==} - '@prisma/fetch-engine@6.8.2': - resolution: {integrity: sha512-lCvikWOgaLOfqXGacEKSNeenvj0n3qR5QvZUOmPE2e1Eh8cMYSobxonCg9rqM6FSdTfbpqp9xwhSAOYfNqSW0g==} + '@prisma/fetch-engine@6.19.0': + resolution: {integrity: sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ==} - '@prisma/get-platform@6.8.2': - resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==} + '@prisma/get-platform@6.19.0': + resolution: {integrity: sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA==} '@scarf/scarf@1.4.0': resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sinclair/typebox@0.34.41': + resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} - '@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==} + '@sinonjs/fake-timers@13.0.5': + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} @@ -1067,27 +1207,26 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/asn1@0.2.4': resolution: {integrity: sha512-V91DSJ2l0h0gRhVP4oBfBzRBN9lAbPUkGDMCnwedqPKX2d84aAMc9CulOvxdw1f7DfEYx99afab+Rsm3e52jhA==} '@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.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} '@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.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - '@types/bcryptjs@3.0.0': - resolution: {integrity: sha512-WRZOuCuaz8UcZZE4R5HXTco2goQSI2XxjGY3hbM/xDvwmqFWd4ivooImsMx65OKM6CtNKbnZ5YL+YwAwK7c1dg==} - deprecated: This is a stub types definition. bcryptjs provides its own type definitions, so you do not need this installed. - - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -1095,23 +1234,23 @@ 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@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/express-serve-static-core@5.0.6': - resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} + '@types/express-serve-static-core@5.1.0': + resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} - '@types/express@5.0.2': - resolution: {integrity: sha512-BtjL3ZwbCQriyb0DGw+Rt12qAXPiBTPs815lsUvtt1Grk0vLRMZNMUZ741d5rjk+UQOxfDiBZ3dxpX00vSkK3g==} + '@types/express@5.0.5': + resolution: {integrity: sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==} - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} - '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -1122,35 +1261,35 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@types/jest@30.0.0': + resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/jsonwebtoken@9.0.10': + resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==} + '@types/jsonwebtoken@9.0.5': resolution: {integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==} - '@types/jsonwebtoken@9.0.7': - resolution: {integrity: sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==} - '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/mime@3.0.4': - resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/multer@1.4.12': - resolution: {integrity: sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg==} + '@types/multer@2.0.0': + resolution: {integrity: sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==} - '@types/mysql@2.15.26': - resolution: {integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==} + '@types/mysql@2.15.27': + resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} - '@types/node@22.13.10': - resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} + '@types/node@20.19.24': + resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==} - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/node@24.10.0': + resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==} '@types/passport-jwt@4.0.1': resolution: {integrity: sha512-Y0Ykz6nWP4jpxgEUYq8NoVZeCQPo1ZndJLfapI249g1jHChvRfZRO/LS3tqu26YgAS/laI1qx98sYGz0IalRXQ==} @@ -1161,80 +1300,196 @@ packages: '@types/passport@1.0.16': resolution: {integrity: sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==} - '@types/pdfkit@0.13.9': - resolution: {integrity: sha512-RDG8Yb1zT7I01FfpwK7nMSA433XWpblMqSCtA5vJlSyavWZb303HUYPCel6JTiDDFqwGLvtAnYbH8N/e0Cb89g==} + '@types/pdfkit@0.17.3': + resolution: {integrity: sha512-E4tp2qFaghqfS4K5TR4Gn1uTIkg0UAkhUgvVIszr5cS6ZmbioPWEkvhNDy3GtR9qdKC8DLQAnaaMlTcf346VsA==} - '@types/qs@6.9.10': - resolution: {integrity: sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==} + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} - '@types/serve-static@1.15.5': - resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/validator@13.11.8': - resolution: {integrity: sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ==} + '@types/validator@13.15.3': + resolution: {integrity: sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==} + + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@17.0.32': - resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + '@types/yargs@17.0.34': + resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} - '@typescript-eslint/eslint-plugin@8.32.1': - resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==} + '@typescript-eslint/eslint-plugin@8.46.3': + resolution: {integrity: sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + '@typescript-eslint/parser': ^8.46.3 eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.32.1': - resolution: {integrity: sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==} + '@typescript-eslint/parser@8.46.3': + resolution: {integrity: sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.46.3': + resolution: {integrity: sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.32.1': - resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==} + '@typescript-eslint/scope-manager@8.46.3': + resolution: {integrity: sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.32.1': - resolution: {integrity: sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==} + '@typescript-eslint/tsconfig-utils@8.46.3': + resolution: {integrity: sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.46.3': + resolution: {integrity: sha512-ZPCADbr+qfz3aiTTYNNkCbUt+cjNwI/5McyANNrFBpVxPt7GqpEYz5ZfdwuFyGUnJ9FdDXbGODUu6iRCI6XRXw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.32.1': - resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} + '@typescript-eslint/types@8.46.3': + resolution: {integrity: sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.32.1': - resolution: {integrity: sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==} + '@typescript-eslint/typescript-estree@8.46.3': + resolution: {integrity: sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.32.1': - resolution: {integrity: sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==} + '@typescript-eslint/utils@8.46.3': + resolution: {integrity: sha512-VXw7qmdkucEx9WkmR3ld/u6VhRyKeiF1uxWwCy/iuNfokjJ7VhsgLSOTjsol8BunSw190zABzpwdNsze2Kpo4g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.32.1': - resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} + '@typescript-eslint/visitor-keys@8.46.3': + resolution: {integrity: sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -1293,6 +1548,12 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1307,8 +1568,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1341,9 +1602,6 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -1351,34 +1609,18 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - ansi-escapes@2.0.0: - resolution: {integrity: sha512-tH/fSoQp4DrEodDK3QpdiWiZTSe7sBJ9eOqcQBZ0o9HTM+5M/viSEn+sPMoTuPjQQ8n++w3QJoPEjt8LVPcrCg==} - engines: {node: '>=4'} - - ansi-escapes@3.2.0: - resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} - engines: {node: '>=4'} - ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - ansi-regex@3.0.1: - resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} - engines: {node: '>=4'} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -1387,12 +1629,12 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - ansis@3.17.0: - resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + ansis@4.1.0: + resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} anymatch@3.1.3: @@ -1427,33 +1669,33 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - axios@1.8.3: - resolution: {integrity: sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==} + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-jest@30.2.0: + resolution: {integrity: sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: - '@babel/core': ^7.8.0 + '@babel/core': ^7.11.0 || ^8.0.0-0 - babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} + babel-plugin-istanbul@7.0.1: + resolution: {integrity: sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==} + engines: {node: '>=12'} - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-jest-hoist@30.2.0: + resolution: {integrity: sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - babel-preset-current-node-syntax@1.0.1: - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': ^7.0.0 || ^8.0.0-0 - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-preset-jest@30.2.0: + resolution: {integrity: sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': ^7.11.0 || ^8.0.0-beta.1 backoff@2.5.0: resolution: {integrity: sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==} @@ -1469,12 +1711,16 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.20: + resolution: {integrity: sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==} + hasBin: true + basic-auth@2.0.1: resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} engines: {node: '>= 0.8'} - bcryptjs@3.0.2: - resolution: {integrity: sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==} + bcryptjs@3.0.3: + resolution: {integrity: sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==} hasBin: true bignumber.js@9.0.0: @@ -1487,21 +1733,21 @@ packages: resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} engines: {node: '>=18'} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - 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.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + browserslist@4.27.0: + resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1529,6 +1775,14 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + c12@3.1.0: + resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -1549,16 +1803,12 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001704: - resolution: {integrity: sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==} + caniuse-lite@1.0.30001751: + resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} centra@2.7.0: resolution: {integrity: sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==} - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -1567,36 +1817,32 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} - chardet@0.4.2: - resolution: {integrity: sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==} - - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + chardet@2.1.0: + resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.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==} + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} engines: {node: '>=8'} - cjs-module-lexer@1.2.3: - resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + cjs-module-lexer@2.1.0: + resolution: {integrity: sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==} class-transformer@0.5.1: resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} - class-validator@0.14.1: - resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==} - - cli-cursor@2.1.0: - resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} - engines: {node: '>=4'} + class-validator@0.14.2: + resolution: {integrity: sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==} cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} @@ -1610,13 +1856,6 @@ packages: resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} - cli-truncate@1.1.0: - resolution: {integrity: sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==} - engines: {node: '>=4'} - - cli-width@2.2.1: - resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} - cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -1637,33 +1876,24 @@ packages: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + collect-v8-coverage@1.0.3: + resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1671,16 +1901,23 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} - comment-json@4.2.5: - resolution: {integrity: sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==} + comment-json@4.4.1: + resolution: {integrity: sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==} engines: {node: '>= 6'} + component-type@2.0.0: + resolution: {integrity: sha512-/1+d/k0Al0uzg4rFAz9fbYOTnT20JYgN7SoaRr5x2cz7kH4Mtj+GQPh7W9UocpzFtxSL8flv6qAOOfJvQGqUjg==} + engines: {node: '>=18'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} @@ -1697,12 +1934,16 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-lite@0.0.1: + resolution: {integrity: sha512-jczNOBIPFsep1+HVBh/RDVU/sdIyTOfpP90jy+D8SwQ4jh8GOJJzXOY0Rs9mogg+gIWeKyREOGt/4xLHdIqtHA==} + engines: {node: '>=18'} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} core-util-is@1.0.2: @@ -1728,18 +1969,9 @@ packages: typescript: optional: true - create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1747,10 +1979,6 @@ packages: crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} - cz-emoji@1.3.2-canary.2: - resolution: {integrity: sha512-XVH9N3P5sepyCRZGVqXJcEkVHT9dPcgBipTmZgkeQUhOJEtaGy0hakMcNdaq1d7N0ZwWVEnsCIs2m/NgLT+SaA==} - engines: {node: '>=4'} - debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -1760,8 +1988,26 @@ packages: supports-color: optional: true - dedent@1.5.1: - resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + dedent@1.7.0: + resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -1774,6 +2020,10 @@ packages: deep-override@1.0.2: resolution: {integrity: sha512-+bAuLuYqaVVUWPaq8rmU8NLTX85p4I5k5/cVdhBioEfH7k+5NlGdv4NoJVQcJRByqzzTWWzTpih+pU1wBTmMow==} + deepmerge-ts@7.1.5: + resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + engines: {node: '>=16.0.0'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -1781,16 +2031,26 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} detect-newline@3.1.0: @@ -1800,10 +2060,6 @@ packages: dfa@1.2.0: resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -1816,6 +2072,10 @@ packages: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -1829,13 +2089,11 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true + effect@3.18.4: + resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} - electron-to-chromium@1.5.118: - resolution: {integrity: sha512-yNDUus0iultYyVoEFLnQeei7LOQkL8wg8GQpkPCRrOlJXlcCwa6eGKZkxQ9ciHsqZyYbj8Jd94X1CTPzGm+uIA==} + electron-to-chromium@1.5.240: + resolution: {integrity: sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -1847,17 +2105,21 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} - env-cmd@10.1.0: - resolution: {integrity: sha512-mMdWTT9XKN7yNth/6N6g2GuKuJTsKMDHlQFUDacb/heQRRWOTIZ42t1rMHnQu4jYxU1ajdTeJM+9eEETlqToMA==} - engines: {node: '>=8.0.0'} + env-cmd@11.0.0: + resolution: {integrity: sha512-gnG7H1PlwPqsGhFJNTv68lsDGyQdK+U9DwLVitcj1+wGq7LeOBgUzZd2puZ710bHcH9NfNeGWe2sbw7pdvAqDw==} + engines: {node: '>=20.10.0'} hasBin: true error-ex@1.3.2: @@ -1871,13 +2133,17 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-module-lexer@1.4.1: - resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1885,10 +2151,6 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} @@ -1897,14 +2159,14 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@10.1.5: - resolution: {integrity: sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==} + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-plugin-prettier@5.4.0: - resolution: {integrity: sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==} + eslint-plugin-prettier@5.5.4: + resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -1921,20 +2183,20 @@ packages: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} - eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.27.0: - resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==} + eslint@9.39.1: + resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1943,8 +2205,8 @@ packages: jiti: optional: true - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esprima@4.0.1: @@ -1952,8 +2214,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: @@ -1987,38 +2249,37 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + exit-x@0.2.2: + resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} engines: {node: '>= 0.8.0'} - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + expect@30.2.0: + resolution: {integrity: sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} express@5.1.0: resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} engines: {node: '>= 18'} - external-editor@2.2.0: - resolution: {integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==} - engines: {node: '>=0.12'} - - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} + exsolve@1.0.7: + resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} extsprintf@1.4.1: resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} engines: {'0': node >=0.6.0} + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -2030,15 +2291,15 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fast-xml-parser@5.2.3: - resolution: {integrity: sha512-OdCYfRqfpuLUFonTNjvd30rCBZUneHpSQkCqfaeWQ9qrKcl6XlWeDBNVwGb+INAIxRshuN2jF+BE0L6gbBO2mw==} + fast-xml-parser@5.3.1: + resolution: {integrity: sha512-jbNkWiv2Ec1A7wuuxk0br0d0aTMUtQ4IkL+l/i1r9PRf6pLXjDgsBsWwO+UyczmQlnehi4Tbc8/KIvxGQe+I/A==} hasBin: true - fastq@1.16.0: - resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -2046,27 +2307,16 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - figures@2.0.0: - resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} - engines: {node: '>=4'} - file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - file-type@20.5.0: - resolution: {integrity: sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==} - engines: {node: '>=18'} - file-type@21.0.0: resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} engines: {node: '>=20'} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - - 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@2.1.0: @@ -2085,8 +2335,17 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true follow-redirects@1.15.6: resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} @@ -2100,8 +2359,8 @@ packages: fontkit@2.0.4: resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} fork-ts-checker-webpack-plugin@9.1.0: @@ -2114,8 +2373,8 @@ packages: form-data-lite@1.0.3: resolution: {integrity: sha512-P7xPqAiOPKzC9Q9aywAZJCQq4QOE5WokPb3HrcWRh7C57RKytueJzoORZAVgHBNvK/lL7E+FxjQjd4X/zbecEQ==} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} forwarded@0.2.0: @@ -2130,8 +2389,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.1.0: + resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2144,10 +2403,6 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - fuse.js@3.6.1: - resolution: {integrity: sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==} - engines: {node: '>=6'} - gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -2172,6 +2427,10 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} + hasBin: true + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2183,8 +2442,12 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@11.0.1: - resolution: {integrity: sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@11.0.3: + resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} hasBin: true @@ -2192,16 +2455,12 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@16.2.0: - resolution: {integrity: sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==} + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} gopd@1.2.0: @@ -2214,24 +2473,25 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + happy-dom@20.0.10: + resolution: {integrity: sha512-6umCCHcjQrhP5oXhrHQQvLB0bwb1UzHAHdsXy+FjtKoYjUhmNZsQL8NivwM1vDvNEChJabVrUYxUnp/ZdYmy2g==} + engines: {node: '>=20.0.0'} has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has-own-prop@2.0.0: - resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} - engines: {node: '>=8'} - has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} - hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} hasown@2.0.2: @@ -2242,12 +2502,6 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true - homedir@0.6.0: - resolution: {integrity: sha512-KZFBHenkVuyyG4uaqRSXqWJr3HTxcaPguM7rU1BlH/mtbDlzaXNSXTa9AhV+fXEjrNemHu9vtLRIaM8/8OW0xA==} - - hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - html-encoding-sniffer@3.0.0: resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} engines: {node: '>=12'} @@ -2272,31 +2526,31 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.0: + resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} + engines: {node: '>=0.10.0'} + 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.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.4: - resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} engines: {node: '>=8'} hasBin: true @@ -2311,20 +2565,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - inquirer-autocomplete-prompt@0.12.2: - resolution: {integrity: sha512-XbgPlnFdAboyUYWIrOkV8vh426BVZWzvbIKRkNY/aCvKhoCSWOO6ZQagAEOGA5ff2iOboNEaT1Wa/cM9ekj8jw==} - - inquirer-maxlength-input-prompt@1.0.2: - resolution: {integrity: sha512-bRs4PfQ7k+M3dDGadFo4//PlEYwWV/tKMNHV0m1jVHSGocyLvlRLuWrNgDuVAmXiEydM5QgfEEP7hbWNtgv0oA==} - engines: {node: '>=6.0.0'} - - inquirer@3.2.0: - resolution: {integrity: sha512-4CyUYMP7lOBkiUU1rR24WGrfRX6SucwbY2Mqb1PdApU24wnTIk4TsnkQwV72dDdIKZ2ycLP+fWCV+tA7wwgoew==} - - inquirer@5.2.0: - resolution: {integrity: sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==} - engines: {node: '>=6.0.0'} - ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -2332,20 +2572,10 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -2390,50 +2620,44 @@ packages: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} - istanbul-lib-instrument@5.2.1: - 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: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} engines: {node: '>=10'} - istanbul-reports@3.1.6: - resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} iterare@1.2.1: resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} engines: {node: '>=6'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.1.1: resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} - jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} - hasBin: true - - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-changed-files@30.2.0: + resolution: {integrity: sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-circus@30.2.0: + resolution: {integrity: sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-cli@30.2.0: + resolution: {integrity: sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2441,57 +2665,56 @@ packages: node-notifier: optional: true - jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-config@30.2.0: + resolution: {integrity: sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@types/node': '*' + esbuild-register: '>=3.4.0' ts-node: '>=9.0.0' peerDependenciesMeta: '@types/node': optional: true + esbuild-register: + optional: true ts-node: optional: true - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-diff@30.2.0: + resolution: {integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-docblock@30.2.0: + resolution: {integrity: sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-each@30.2.0: + resolution: {integrity: sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-node@30.2.0: + resolution: {integrity: sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@30.2.0: + resolution: {integrity: sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-leak-detector@30.2.0: + resolution: {integrity: sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-matcher-utils@30.2.0: + resolution: {integrity: sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@30.2.0: + resolution: {integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@30.2.0: + resolution: {integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-pnp-resolver@1.2.3: resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} @@ -2502,53 +2725,53 @@ packages: jest-resolve: optional: true - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-regex-util@30.0.1: + resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve-dependencies@30.2.0: + resolution: {integrity: sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve@30.2.0: + resolution: {integrity: sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runner@30.2.0: + resolution: {integrity: sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runtime@30.2.0: + resolution: {integrity: sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-snapshot@30.2.0: + resolution: {integrity: sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@30.2.0: + resolution: {integrity: sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-validate@30.2.0: + resolution: {integrity: sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-watcher@30.2.0: + resolution: {integrity: sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@30.2.0: + resolution: {integrity: sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest@30.2.0: + resolution: {integrity: sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2556,8 +2779,8 @@ packages: node-notifier: optional: true - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true jpeg-exif@1.1.4: @@ -2574,9 +2797,9 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} hasBin: true json-buffer@3.0.1: @@ -2608,8 +2831,8 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} @@ -2624,10 +2847,6 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - klona@2.0.6: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} @@ -2646,9 +2865,9 @@ 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.3.1: - resolution: {integrity: sha512-g8mxobOSeuxVkXRT9JZBGUvfDjXIpQPEHH5kYG9UjrIlWV5Rqxq+MMmqzlSh4OqSXh+3lFvzyYu+lsJldoZvvA==} - engines: {node: '>=18'} + ldapts@8.0.9: + resolution: {integrity: sha512-6UwfVFUX0Yp5XFY8ST0p9sytpmHGNm32GehI/dq4HuA3pL5kh0AceHBSfowv+cutIJFQnfBZmBo/6cnj87JDqA==} + engines: {node: '>=20'} leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -2658,12 +2877,11 @@ 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==} + lexical@0.38.2: + resolution: {integrity: sha512-JJmfsG3c4gwBHzUGffbV7ifMNkKAWMCnYE3xJl87gty7hjyV5f3xq7eqTjP5HFYvO4XpjJvvWO2/djHp5S10tw==} - 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. + libphonenumber-js@1.12.24: + resolution: {integrity: sha512-l5IlyL9AONj4voSd7q9xkuQOL4u8Ty44puTic7J88CmdXkxfGsRfoVLXHCxppwehgpb/Chdb80FFehHqjN3ItQ==} linebreak@1.1.0: resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} @@ -2671,12 +2889,12 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - load-esm@1.0.2: - resolution: {integrity: sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==} + load-esm@1.0.3: + resolution: {integrity: sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==} engines: {node: '>=13.2.0'} - loader-runner@4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} locate-path@5.0.0: @@ -2696,9 +2914,6 @@ packages: lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - lodash.invoke@4.5.2: - resolution: {integrity: sha512-SC4Usc0XbIKuz3eH7oNwPqibKHfTJSGVZwO/6eGhdoPzqexOY7z43pKo8xz0M5zzXSRteADV6fW7cRf6Ru0+VA==} - lodash.isboolean@3.0.3: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} @@ -2732,9 +2947,6 @@ packages: lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - lodash.partialright@4.2.1: - resolution: {integrity: sha512-yebmPMQZH7i4El6SdJTW9rn8irWl8VTcsmiWqm/I4sY8/ZjbSo0Z512HL6soeAu3mh5rhx5uIIo6kYJOQXbCxw==} - lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} @@ -2745,8 +2957,11 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.2.2: + resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -2769,6 +2984,10 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + mariadb@3.4.5: + resolution: {integrity: sha512-gThTYkhIS5rRqkVr+Y0cIdzr+GRqJ9sA2Q34e0yzmyhMCwyApf3OKAC1jnF23aSlIOqJuyaUFUcj7O1qZslmmQ==} + engines: {node: '>= 14'} + matchit@1.1.0: resolution: {integrity: sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==} engines: {node: '>=6'} @@ -2800,8 +3019,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} mime-db@1.52.0: @@ -2828,25 +3047,17 @@ packages: engines: {node: '>=4'} hasBin: true - mimic-fn@1.2.0: - resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} - engines: {node: '>=4'} - mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -2865,17 +3076,10 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multer@1.4.5-lts.1: - resolution: {integrity: sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==} - engines: {node: '>= 6.0.0'} - - multer@2.0.0: - resolution: {integrity: sha512-bS8rPZurbAuHGAnApbM9d4h1wSoYqrOqkE+6a64KLMK9yWU7gJXBDDVklKQ3TPi9DRb85cRs6yXaC0+cjxRtRg==} + multer@2.0.2: + resolution: {integrity: sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==} engines: {node: '>= 10.16.0'} - mute-stream@0.0.7: - resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} - mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2884,6 +3088,11 @@ packages: resolution: {integrity: sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==} engines: {node: '>= 0.6'} + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2900,8 +3109,8 @@ packages: '@nestjs/common': '>6.11.0' '@nestjs/core': '>6.11.0' - nock@14.0.4: - resolution: {integrity: sha512-86fh+gIKH8H02+y0/HKAOZZXn6OwgzXvl6JYwfjvKkoKxUWz54wIIDU/+w24xzMvk/R8pNVXOrvTubyl+Ml6cg==} + nock@14.0.10: + resolution: {integrity: sha512-Q7HjkpyPeLa0ZVZC5qpxBt5EyLczFJ91MEewQiIi9taWuA0KB/MDJlUWtON+7dGouVdADTQsf9RA7TZk6D8VMw==} engines: {node: '>=18.20.0 <20 || >=20.12.1'} node-abort-controller@3.1.1: @@ -2910,14 +3119,14 @@ packages: node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - - normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + node-releases@2.0.26: + resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -2927,6 +3136,11 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + nypm@0.6.2: + resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2935,6 +3149,9 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -2942,10 +3159,6 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@2.0.1: - resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} - engines: {node: '>=4'} - onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -2957,18 +3170,14 @@ packages: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true - 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: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} @@ -2998,14 +3207,10 @@ packages: pactum-matchers@1.1.7: resolution: {integrity: sha512-RqwewcUje6vhcYQGbPfdSXkcp/Vtwn4WmmTWLSmqp0CGxBroCEqRg3JMIjkjQTZCd2VmG+tTcQw+n4P/iuqv3Q==} - pactum@3.7.6: - resolution: {integrity: sha512-LopFf+CwhdoHhBGK8VYWuyfSn6ICCOEWoPzBlMkou9iFWsZN47lZyFXJEfK8UOtdI1fZaFx2JxZcls+RfYAgAA==} + pactum@3.8.0: + resolution: {integrity: sha512-zMVXkhdNf0RYaTPkH8GWJTtf10MzDoA/+8wtdJBFu+lg4CbB+Zk6WxQw3isowTstKM+MNmKgWcdUnFYNW6B5Mw==} engines: {node: '>=10'} - pad@2.3.0: - resolution: {integrity: sha512-lxrgnOG5AXmzMRT1O5urWtYFxHnFSE+QntgTHij1nvS4W+ubhQLmQRHmZXDeEvk9I00itAixLqU9Q6fE0gW3sw==} - engines: {node: '>= 4.0.0'} - pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -3031,8 +3236,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: @@ -3047,34 +3252,37 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} path-scurry@2.0.0: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} - path-to-regexp@8.2.0: - resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} - engines: {node: '>=16'} + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pause@0.0.1: resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} - pdfkit@0.16.0: - resolution: {integrity: sha512-oXMxkIqXH4uTAtohWdYA41i/f6i2ReB78uhgizN8H4hJEpgR3/Xjy3iu2InNAuwCIabN3PVs8P1D6G4+W2NH0A==} + pdfkit@0.17.2: + resolution: {integrity: sha512-UnwF5fXy08f0dnp4jchFYAROKMNTaPqb/xgR8GtCzIcqoTnbOqtp3bwKvO4688oHI6vzEEs8Q6vqqEnC5IUELw==} - peek-readable@7.0.0: - resolution: {integrity: sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==} - engines: {node: '>=18'} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} phin@3.7.1: resolution: {integrity: sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==} engines: {node: '>= 8'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -3087,14 +3295,21 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -3121,22 +3336,17 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} - prettier@1.19.1: - resolution: {integrity: sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==} - engines: {node: '>=4'} - hasBin: true - - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} engines: {node: '>=14'} hasBin: true - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@30.2.0: + resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - prisma@6.8.2: - resolution: {integrity: sha512-JNricTXQxzDtRS7lCGGOB4g5DJ91eg3nozdubXze3LpcMl1oWwcFddrj++Up3jnRE6X/3gB/xz3V+ecBk/eEGA==} + prisma@6.19.0: + resolution: {integrity: sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw==} engines: {node: '>=18.18'} hasBin: true peerDependencies: @@ -3145,13 +3355,13 @@ packages: typescript: optional: true + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - propagate@2.0.1: resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} engines: {node: '>= 8'} @@ -3167,8 +3377,11 @@ 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==} + + pure-rand@7.0.1: + resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} qs@6.13.0: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} @@ -3188,27 +3401,19 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} - - react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + raw-body@3.0.1: + resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} + engines: {node: '>= 0.10'} - read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} readable-stream@2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3220,10 +3425,6 @@ packages: reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -3247,18 +3448,6 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - restore-cursor@2.0.0: - resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} - engines: {node: '>=4'} - restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -3266,31 +3455,17 @@ packages: restructure@3.0.2: resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} - run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - rx-lite-aggregates@4.0.8: - resolution: {integrity: sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==} - - rx-lite@4.0.8: - resolution: {integrity: sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==} - - rxjs@5.5.12: - resolution: {integrity: sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==} - engines: {npm: '>=2.0.0'} - rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} @@ -3310,17 +3485,13 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} - schema-utils@4.3.0: - resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} secure-compare@3.0.1: resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==} - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -3330,8 +3501,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true @@ -3349,8 +3520,8 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -3384,20 +3555,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slice-ansi@1.0.0: - resolution: {integrity: sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==} - engines: {node: '>=4'} - source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} @@ -3412,17 +3573,9 @@ packages: resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} engines: {node: '>= 8'} - spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - - spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - - 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==} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -3439,6 +3592,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -3453,10 +3610,6 @@ packages: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} - string-width@2.1.1: - resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} - engines: {node: '>=4'} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -3471,16 +3624,12 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@4.0.0: - resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} - engines: {node: '>=4'} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -3502,14 +3651,10 @@ packages: strnum@2.1.1: resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} - strtok3@10.2.2: - resolution: {integrity: sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==} + strtok3@10.3.4: + resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} engines: {node: '>=18'} - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -3518,27 +3663,19 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - swagger-ui-dist@5.21.0: - resolution: {integrity: sha512-E0K3AB6HvQd8yQNSMR7eE5bk+323AUxjtCz/4ZNKiahOlPhPJxqn3UPIGs00cyY/dhrTDJ61L7C/a8u6zhGrZg==} - - symbol-observable@1.0.1: - resolution: {integrity: sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==} - engines: {node: '>=0.10.0'} + swagger-ui-dist@5.29.4: + resolution: {integrity: sha512-gJFDz/gyLOCQtWwAgqs6Rk78z9ONnqTnlW11gimG9nLap8drKa3AJBKpzIQMIjl5PD2Ix+Tn+mc/tfoT2tgsng==} symbol-observable@4.0.0: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} engines: {node: '>=0.10'} - synckit@0.11.6: - resolution: {integrity: sha512-2pR2ubZSV64f/vqm9eLPz/KOvR9Dm+Co/5ChLgeHl0yEDRc6h5hXHoxEQH8Y5Ljycozd3p1k5TTSVdzYGkPvLw==} + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} terser-webpack-plugin@5.3.14: @@ -3557,8 +3694,8 @@ packages: uglify-js: optional: true - terser@5.39.0: - resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + terser@5.44.0: + resolution: {integrity: sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==} engines: {node: '>=10'} hasBin: true @@ -3566,23 +3703,16 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -3591,12 +3721,12 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - token-types@6.0.0: - resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} + token-types@6.1.1: + resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==} engines: {node: '>=14.16'} - tr46@5.0.0: - resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} tree-kill@1.2.2: @@ -3613,17 +3743,18 @@ packages: peerDependencies: typescript: '>=4.8.4' - ts-jest@29.2.6: - resolution: {integrity: sha512-yTNZVZqc8lSixm+QGVFcPe6+yj7+TWZwIesuOWvfcn4B9bz5x4NDzVCQQjOs7Hfouu36aEqfEbo9Qpo+gq8dDg==} + ts-jest@29.4.5: + resolution: {integrity: sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 esbuild: '*' - jest: ^29.0.0 + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 typescript: '>=4.3 <6' peerDependenciesMeta: '@babel/core': @@ -3636,9 +3767,11 @@ packages: optional: true esbuild: optional: true + jest-util: + optional: true - ts-loader@9.5.2: - resolution: {integrity: sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==} + ts-loader@9.5.4: + resolution: {integrity: sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==} engines: {node: '>=12.0.0'} peerDependencies: typescript: '*' @@ -3684,13 +3817,9 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} - - type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} @@ -3703,28 +3832,41 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.32.1: - resolution: {integrity: sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==} + typescript-eslint@8.46.3: + resolution: {integrity: sha512-bAfgMavTuGo+8n6/QQDVQz4tZ4f7Soqg53RbrlZQEoAltYop/XR4RAts/I0BrO3TTClTSTFJ0wYbla+P8cEWJA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' typescript@5.8.3: resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + uid@2.0.2: resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} engines: {node: '>=8'} - uint8array-extras@1.4.0: - resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} engines: {node: '>=18'} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} unicode-properties@1.4.1: resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} @@ -3744,8 +3886,11 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -3763,22 +3908,19 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} - uuid@11.0.5: - resolution: {integrity: sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==} + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} 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.15.15: + resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} engines: {node: '>= 0.10'} vary@1.1.2: @@ -3800,8 +3942,8 @@ packages: walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - watchpack@2.4.2: - resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} engines: {node: '>=10.13.0'} wcwidth@1.0.1: @@ -3815,12 +3957,12 @@ packages: resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} engines: {node: '>=6'} - webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} engines: {node: '>=10.13.0'} - webpack@5.99.6: - resolution: {integrity: sha512-TJOLrJ6oeccsGWPl7ujCYuc0pIq2cNsuD6GZDma8i5o5Npvcco/z+NKvZSFsP0/x6SShVb0+X2JK/JHUjKY9dQ==} + webpack@5.100.2: + resolution: {integrity: sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -3833,8 +3975,12 @@ packages: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} - whatwg-url@14.1.1: - resolution: {integrity: sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==} + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} which@2.0.2: @@ -3842,6 +3988,13 @@ packages: engines: {node: '>= 8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -3857,9 +4010,9 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} @@ -3891,20 +4044,13 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yoctocolors-cjs@2.1.2: - resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} snapshots: - '@aashutoshrathi/word-wrap@1.2.6': {} - - '@ampproject/remapping@2.2.1': - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.25 - - '@angular-devkit/core@19.2.6(chokidar@4.0.3)': + '@angular-devkit/core@19.2.15(chokidar@4.0.3)': dependencies: ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) @@ -3915,7 +4061,7 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@angular-devkit/core@19.2.8(chokidar@4.0.3)': + '@angular-devkit/core@19.2.17(chokidar@4.0.3)': dependencies: ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) @@ -3926,11 +4072,11 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@angular-devkit/schematics-cli@19.2.8(@types/node@22.13.10)(chokidar@4.0.3)': + '@angular-devkit/schematics-cli@19.2.15(@types/node@24.10.0)(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 19.2.8(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.8(chokidar@4.0.3) - '@inquirer/prompts': 7.3.2(@types/node@22.13.10) + '@angular-devkit/core': 19.2.15(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.15(chokidar@4.0.3) + '@inquirer/prompts': 7.3.2(@types/node@24.10.0) ansi-colors: 4.1.3 symbol-observable: 4.0.0 yargs-parser: 21.1.1 @@ -3938,9 +4084,9 @@ snapshots: - '@types/node' - chokidar - '@angular-devkit/schematics@19.2.6(chokidar@4.0.3)': + '@angular-devkit/schematics@19.2.15(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 19.2.6(chokidar@4.0.3) + '@angular-devkit/core': 19.2.15(chokidar@4.0.3) jsonc-parser: 3.3.1 magic-string: 0.30.17 ora: 5.4.1 @@ -3948,9 +4094,9 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/schematics@19.2.8(chokidar@4.0.3)': + '@angular-devkit/schematics@19.2.17(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 19.2.8(chokidar@4.0.3) + '@angular-devkit/core': 19.2.17(chokidar@4.0.3) jsonc-parser: 3.3.1 magic-string: 0.30.17 ora: 5.4.1 @@ -3960,273 +4106,275 @@ snapshots: '@arr/every@1.0.1': {} - '@babel/code-frame@7.23.5': + '@babel/code-frame@7.27.1': dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 - '@babel/compat-data@7.23.5': {} + '@babel/compat-data@7.28.5': {} - '@babel/core@7.23.6': + '@babel/core@7.28.5': 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 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.3 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.28.5': dependencies: - '@babel/types': 7.23.6 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.23.5 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.24.4 + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.27.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-environment-visitor@7.22.20': {} + '@babel/helper-globals@7.28.0': {} - '@babel/helper-function-name@7.23.0': + '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color - '@babel/helper-hoist-variables@7.22.5': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: - '@babel/types': 7.23.6 + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color - '@babel/helper-module-imports@7.22.15': - dependencies: - '@babel/types': 7.23.6 + '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-module-transforms@7.23.3(@babel/core@7.23.6)': - 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/helper-string-parser@7.27.1': {} - '@babel/helper-plugin-utils@7.22.5': {} + '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-simple-access@7.22.5': - dependencies: - '@babel/types': 7.23.6 + '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-split-export-declaration@7.22.6': + '@babel/helpers@7.28.4': dependencies: - '@babel/types': 7.23.6 - - '@babel/helper-string-parser@7.23.4': {} + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 - '@babel/helper-validator-identifier@7.22.20': {} - - '@babel/helper-validator-option@7.23.5': {} + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 - '@babel/helpers@7.23.6': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.5)': dependencies: - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.6 - '@babel/types': 7.23.6 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/highlight@7.23.4': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.5)': dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/parser@7.23.6': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.5)': dependencies: - '@babel/types': 7.23.6 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.6)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.6)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.6)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@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.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@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.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@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.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@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.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@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.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@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.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.6)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/template@7.22.15': + '@babel/template@7.27.2': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 - '@babel/traverse@7.23.6': + '@babel/traverse@7.28.5': 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.4.0 - globals: 11.12.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.23.6': + '@babel/types@7.28.5': dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 '@bcoe/v8-coverage@0.2.3': {} + '@borewit/text-codec@0.1.1': {} + '@colors/colors@1.5.0': optional: true + '@commander-js/extra-typings@13.1.0(commander@13.1.0)': + dependencies: + commander: 13.1.0 + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@emnapi/runtime@1.3.1': + '@emnapi/core@1.6.0': dependencies: + '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.27.0(jiti@2.4.2))': + '@emnapi/runtime@1.7.0': dependencies: - eslint: 9.27.0(jiti@2.4.2) - eslint-visitor-keys: 3.4.3 + tslib: 2.8.1 + optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0(jiti@2.4.2))': + '@emnapi/wasi-threads@1.1.0': dependencies: - eslint: 9.27.0(jiti@2.4.2) - eslint-visitor-keys: 3.4.3 + tslib: 2.8.1 + optional: true - '@eslint-community/regexpp@4.10.0': {} + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1(jiti@2.6.1))': + dependencies: + eslint: 9.39.1(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.20.0': + '@eslint/config-array@0.21.1': dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.0 + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.2.2': {} + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 - '@eslint/core@0.14.0': + '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.0 - espree: 10.3.0 + debug: 4.4.3 + espree: 10.4.0 globals: 14.0.0 - ignore: 5.3.0 - import-fresh: 3.3.0 + ignore: 5.3.2 + import-fresh: 3.3.1 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.27.0': {} + '@eslint/js@9.39.1': {} - '@eslint/object-schema@2.1.6': {} + '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.3.1': + '@eslint/plugin-kit@0.4.1': dependencies: - '@eslint/core': 0.14.0 + '@eslint/core': 0.17.0 levn: 0.4.1 '@exodus/schemasafe@1.3.0': {} - '@faker-js/faker@9.8.0': {} + '@faker-js/faker@9.9.0': {} - '@fast-csv/parse@5.0.2': + '@fast-csv/parse@5.0.5': dependencies: lodash.escaperegexp: 4.1.2 lodash.groupby: 4.6.0 @@ -4237,228 +4385,262 @@ snapshots: '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.6': + '@humanfs/node@0.16.7': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.3 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} - '@img/sharp-darwin-arm64@0.33.5': + '@img/colour@1.0.0': {} + + '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-arm64': 1.2.4 optional: true - '@img/sharp-darwin-x64@0.33.5': + '@img/sharp-darwin-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': optional: true - '@img/sharp-libvips-darwin-arm64@1.0.4': + '@img/sharp-libvips-darwin-x64@1.2.4': optional: true - '@img/sharp-libvips-darwin-x64@1.0.4': + '@img/sharp-libvips-linux-arm64@1.2.4': optional: true - '@img/sharp-libvips-linux-arm64@1.0.4': + '@img/sharp-libvips-linux-arm@1.2.4': optional: true - '@img/sharp-libvips-linux-arm@1.0.5': + '@img/sharp-libvips-linux-ppc64@1.2.4': optional: true - '@img/sharp-libvips-linux-s390x@1.0.4': + '@img/sharp-libvips-linux-riscv64@1.2.4': optional: true - '@img/sharp-libvips-linux-x64@1.0.4': + '@img/sharp-libvips-linux-s390x@1.2.4': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + '@img/sharp-libvips-linux-x64@1.2.4': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.0.4': + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': optional: true - '@img/sharp-linux-arm64@0.33.5': + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 optional: true - '@img/sharp-linux-arm@0.33.5': + '@img/sharp-linux-riscv64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-riscv64': 1.2.4 optional: true - '@img/sharp-linux-s390x@0.33.5': + '@img/sharp-linux-s390x@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 optional: true - '@img/sharp-linux-x64@0.33.5': + '@img/sharp-linux-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.2.4 optional: true - '@img/sharp-linuxmusl-arm64@0.33.5': + '@img/sharp-linuxmusl-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 optional: true - '@img/sharp-linuxmusl-x64@0.33.5': + '@img/sharp-linuxmusl-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 optional: true - '@img/sharp-wasm32@0.33.5': + '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.3.1 + '@emnapi/runtime': 1.7.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': optional: true - '@img/sharp-win32-ia32@0.33.5': + '@img/sharp-win32-ia32@0.34.5': optional: true - '@img/sharp-win32-x64@0.33.5': + '@img/sharp-win32-x64@0.34.5': optional: true - '@inquirer/checkbox@4.1.8(@types/node@22.13.10)': + '@inquirer/ansi@1.0.1': {} + + '@inquirer/checkbox@4.3.0(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.13.10) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.2 + '@inquirer/ansi': 1.0.1 + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/figures': 1.0.14 + '@inquirer/type': 3.0.9(@types/node@24.10.0) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/confirm@5.1.12(@types/node@22.13.10)': + '@inquirer/confirm@5.1.19(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/type': 3.0.7(@types/node@22.13.10) + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/type': 3.0.9(@types/node@24.10.0) optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/core@10.1.13(@types/node@22.13.10)': + '@inquirer/core@10.3.0(@types/node@24.10.0)': dependencies: - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.13.10) - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.1 + '@inquirer/figures': 1.0.14 + '@inquirer/type': 3.0.9(@types/node@24.10.0) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.10.0 + + '@inquirer/editor@4.2.21(@types/node@24.10.0)': + dependencies: + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/external-editor': 1.0.2(@types/node@24.10.0) + '@inquirer/type': 3.0.9(@types/node@24.10.0) optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/editor@4.2.13(@types/node@22.13.10)': + '@inquirer/expand@4.0.21(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/type': 3.0.7(@types/node@22.13.10) - external-editor: 3.1.0 + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/type': 3.0.9(@types/node@24.10.0) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/expand@4.0.15(@types/node@22.13.10)': + '@inquirer/external-editor@1.0.2(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/type': 3.0.7(@types/node@22.13.10) - yoctocolors-cjs: 2.1.2 + chardet: 2.1.0 + iconv-lite: 0.7.0 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/figures@1.0.12': {} + '@inquirer/figures@1.0.14': {} - '@inquirer/input@4.1.12(@types/node@22.13.10)': + '@inquirer/input@4.2.5(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/type': 3.0.7(@types/node@22.13.10) + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/type': 3.0.9(@types/node@24.10.0) optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/number@3.0.15(@types/node@22.13.10)': + '@inquirer/number@3.0.21(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/type': 3.0.7(@types/node@22.13.10) + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/type': 3.0.9(@types/node@24.10.0) optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/password@4.0.15(@types/node@22.13.10)': + '@inquirer/password@4.0.21(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/type': 3.0.7(@types/node@22.13.10) - ansi-escapes: 4.3.2 + '@inquirer/ansi': 1.0.1 + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/type': 3.0.9(@types/node@24.10.0) optionalDependencies: - '@types/node': 22.13.10 - - '@inquirer/prompts@7.3.2(@types/node@22.13.10)': - dependencies: - '@inquirer/checkbox': 4.1.8(@types/node@22.13.10) - '@inquirer/confirm': 5.1.12(@types/node@22.13.10) - '@inquirer/editor': 4.2.13(@types/node@22.13.10) - '@inquirer/expand': 4.0.15(@types/node@22.13.10) - '@inquirer/input': 4.1.12(@types/node@22.13.10) - '@inquirer/number': 3.0.15(@types/node@22.13.10) - '@inquirer/password': 4.0.15(@types/node@22.13.10) - '@inquirer/rawlist': 4.1.3(@types/node@22.13.10) - '@inquirer/search': 3.0.15(@types/node@22.13.10) - '@inquirer/select': 4.2.3(@types/node@22.13.10) + '@types/node': 24.10.0 + + '@inquirer/prompts@7.3.2(@types/node@24.10.0)': + dependencies: + '@inquirer/checkbox': 4.3.0(@types/node@24.10.0) + '@inquirer/confirm': 5.1.19(@types/node@24.10.0) + '@inquirer/editor': 4.2.21(@types/node@24.10.0) + '@inquirer/expand': 4.0.21(@types/node@24.10.0) + '@inquirer/input': 4.2.5(@types/node@24.10.0) + '@inquirer/number': 3.0.21(@types/node@24.10.0) + '@inquirer/password': 4.0.21(@types/node@24.10.0) + '@inquirer/rawlist': 4.1.9(@types/node@24.10.0) + '@inquirer/search': 3.2.0(@types/node@24.10.0) + '@inquirer/select': 4.4.0(@types/node@24.10.0) optionalDependencies: - '@types/node': 22.13.10 - - '@inquirer/prompts@7.4.1(@types/node@22.13.10)': - dependencies: - '@inquirer/checkbox': 4.1.8(@types/node@22.13.10) - '@inquirer/confirm': 5.1.12(@types/node@22.13.10) - '@inquirer/editor': 4.2.13(@types/node@22.13.10) - '@inquirer/expand': 4.0.15(@types/node@22.13.10) - '@inquirer/input': 4.1.12(@types/node@22.13.10) - '@inquirer/number': 3.0.15(@types/node@22.13.10) - '@inquirer/password': 4.0.15(@types/node@22.13.10) - '@inquirer/rawlist': 4.1.3(@types/node@22.13.10) - '@inquirer/search': 3.0.15(@types/node@22.13.10) - '@inquirer/select': 4.2.3(@types/node@22.13.10) + '@types/node': 24.10.0 + + '@inquirer/prompts@7.8.0(@types/node@24.10.0)': + dependencies: + '@inquirer/checkbox': 4.3.0(@types/node@24.10.0) + '@inquirer/confirm': 5.1.19(@types/node@24.10.0) + '@inquirer/editor': 4.2.21(@types/node@24.10.0) + '@inquirer/expand': 4.0.21(@types/node@24.10.0) + '@inquirer/input': 4.2.5(@types/node@24.10.0) + '@inquirer/number': 3.0.21(@types/node@24.10.0) + '@inquirer/password': 4.0.21(@types/node@24.10.0) + '@inquirer/rawlist': 4.1.9(@types/node@24.10.0) + '@inquirer/search': 3.2.0(@types/node@24.10.0) + '@inquirer/select': 4.4.0(@types/node@24.10.0) optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/rawlist@4.1.3(@types/node@22.13.10)': + '@inquirer/rawlist@4.1.9(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/type': 3.0.7(@types/node@22.13.10) - yoctocolors-cjs: 2.1.2 + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/type': 3.0.9(@types/node@24.10.0) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/search@3.0.15(@types/node@22.13.10)': + '@inquirer/search@3.2.0(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.13.10) - yoctocolors-cjs: 2.1.2 + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/figures': 1.0.14 + '@inquirer/type': 3.0.9(@types/node@24.10.0) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/select@4.2.3(@types/node@22.13.10)': + '@inquirer/select@4.4.0(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.13.10) - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.13.10) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.2 + '@inquirer/ansi': 1.0.1 + '@inquirer/core': 10.3.0(@types/node@24.10.0) + '@inquirer/figures': 1.0.14 + '@inquirer/type': 3.0.9(@types/node@24.10.0) + yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@inquirer/type@3.0.7(@types/node@22.13.10)': + '@inquirer/type@3.0.9(@types/node@24.10.0)': optionalDependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 @@ -4473,202 +4655,298 @@ snapshots: '@istanbuljs/schema@0.1.3': {} - '@jest/console@29.7.0': + '@jest/console@30.2.0': dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.13.10 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 + jest-message-util: 30.2.0 + jest-util: 30.2.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3))': + '@jest/core@30.2.0(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3))': dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.13.10 + '@jest/console': 30.2.0 + '@jest/pattern': 30.0.1 + '@jest/reporters': 30.2.0 + '@jest/test-result': 30.2.0 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 ansi-escapes: 4.3.2 chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 + ci-info: 4.3.1 + exit-x: 0.2.2 graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.5 - pretty-format: 29.7.0 + jest-changed-files: 30.2.0 + jest-config: 30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)) + jest-haste-map: 30.2.0 + jest-message-util: 30.2.0 + jest-regex-util: 30.0.1 + jest-resolve: 30.2.0 + jest-resolve-dependencies: 30.2.0 + jest-runner: 30.2.0 + jest-runtime: 30.2.0 + jest-snapshot: 30.2.0 + jest-util: 30.2.0 + jest-validate: 30.2.0 + jest-watcher: 30.2.0 + micromatch: 4.0.8 + pretty-format: 30.2.0 slash: 3.0.0 - strip-ansi: 6.0.1 transitivePeerDependencies: - babel-plugin-macros + - esbuild-register - supports-color - ts-node - '@jest/environment@29.7.0': + '@jest/diff-sequences@30.0.1': {} + + '@jest/environment@30.2.0': dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.13.10 - jest-mock: 29.7.0 + '@jest/fake-timers': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 + jest-mock: 30.2.0 - '@jest/expect-utils@29.7.0': + '@jest/expect-utils@30.2.0': dependencies: - jest-get-type: 29.6.3 + '@jest/get-type': 30.1.0 - '@jest/expect@29.7.0': + '@jest/expect@30.2.0': dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 + expect: 30.2.0 + jest-snapshot: 30.2.0 transitivePeerDependencies: - supports-color - '@jest/fake-timers@29.7.0': + '@jest/fake-timers@30.2.0': dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.13.10 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 + '@jest/types': 30.2.0 + '@sinonjs/fake-timers': 13.0.5 + '@types/node': 24.10.0 + jest-message-util: 30.2.0 + jest-mock: 30.2.0 + jest-util: 30.2.0 + + '@jest/get-type@30.1.0': {} - '@jest/globals@29.7.0': + '@jest/globals@30.2.0': dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 + '@jest/environment': 30.2.0 + '@jest/expect': 30.2.0 + '@jest/types': 30.2.0 + jest-mock: 30.2.0 transitivePeerDependencies: - supports-color - '@jest/reporters@29.7.0': + '@jest/pattern@30.0.1': + dependencies: + '@types/node': 24.10.0 + jest-regex-util: 30.0.1 + + '@jest/reporters@30.2.0': dependencies: '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.13.10 + '@jest/console': 30.2.0 + '@jest/test-result': 30.2.0 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + '@jridgewell/trace-mapping': 0.3.31 + '@types/node': 24.10.0 chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 + collect-v8-coverage: 1.0.3 + exit-x: 0.2.2 + glob: 10.4.5 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 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.2.0 + jest-message-util: 30.2.0 + jest-util: 30.2.0 + jest-worker: 30.2.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 - '@jest/schemas@29.6.3': + '@jest/schemas@30.0.5': + dependencies: + '@sinclair/typebox': 0.34.41 + + '@jest/snapshot-utils@30.2.0': dependencies: - '@sinclair/typebox': 0.27.8 + '@jest/types': 30.2.0 + chalk: 4.1.2 + graceful-fs: 4.2.11 + natural-compare: 1.4.0 - '@jest/source-map@29.6.3': + '@jest/source-map@30.0.1': dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 callsites: 3.1.0 graceful-fs: 4.2.11 - '@jest/test-result@29.7.0': + '@jest/test-result@30.2.0': dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 + '@jest/console': 30.2.0 + '@jest/types': 30.2.0 '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 + collect-v8-coverage: 1.0.3 - '@jest/test-sequencer@29.7.0': + '@jest/test-sequencer@30.2.0': dependencies: - '@jest/test-result': 29.7.0 + '@jest/test-result': 30.2.0 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 + jest-haste-map: 30.2.0 slash: 3.0.0 - '@jest/transform@29.7.0': + '@jest/transform@30.2.0': dependencies: - '@babel/core': 7.23.6 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1 + '@babel/core': 7.28.5 + '@jest/types': 30.2.0 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 7.0.1 chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.5 - pirates: 4.0.6 + jest-haste-map: 30.2.0 + jest-regex-util: 30.0.1 + jest-util: 30.2.0 + micromatch: 4.0.8 + pirates: 4.0.7 slash: 3.0.0 - write-file-atomic: 4.0.2 + write-file-atomic: 5.0.1 transitivePeerDependencies: - supports-color - '@jest/types@29.6.3': + '@jest/types@30.2.0': dependencies: - '@jest/schemas': 29.6.3 + '@jest/pattern': 30.0.1 + '@jest/schemas': 30.0.5 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.13.10 - '@types/yargs': 17.0.32 + '@types/node': 24.10.0 + '@types/yargs': 17.0.34 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.3': + '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.1': {} - '@jridgewell/set-array@1.1.2': {} + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/source-map@0.3.5': + '@jridgewell/source-map@0.3.11': dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/sourcemap-codec@1.4.15': {} - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.25': + '@jridgewell/trace-mapping@0.3.31': dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + '@lexical/clipboard@0.38.2': + dependencies: + '@lexical/html': 0.38.2 + '@lexical/list': 0.38.2 + '@lexical/selection': 0.38.2 + '@lexical/utils': 0.38.2 + lexical: 0.38.2 + + '@lexical/code@0.38.2': + dependencies: + '@lexical/utils': 0.38.2 + lexical: 0.38.2 + prismjs: 1.30.0 + + '@lexical/dragon@0.38.2': + dependencies: + '@lexical/extension': 0.38.2 + lexical: 0.38.2 + + '@lexical/extension@0.38.2': + dependencies: + '@lexical/utils': 0.38.2 + '@preact/signals-core': 1.12.1 + lexical: 0.38.2 + + '@lexical/headless@0.38.2': + dependencies: + happy-dom: 20.0.10 + lexical: 0.38.2 + + '@lexical/html@0.38.2': + dependencies: + '@lexical/selection': 0.38.2 + '@lexical/utils': 0.38.2 + lexical: 0.38.2 + + '@lexical/link@0.38.2': + dependencies: + '@lexical/extension': 0.38.2 + '@lexical/utils': 0.38.2 + lexical: 0.38.2 + + '@lexical/list@0.38.2': + dependencies: + '@lexical/extension': 0.38.2 + '@lexical/selection': 0.38.2 + '@lexical/utils': 0.38.2 + lexical: 0.38.2 + + '@lexical/rich-text@0.38.2': + dependencies: + '@lexical/clipboard': 0.38.2 + '@lexical/dragon': 0.38.2 + '@lexical/selection': 0.38.2 + '@lexical/utils': 0.38.2 + lexical: 0.38.2 + + '@lexical/selection@0.38.2': + dependencies: + lexical: 0.38.2 + + '@lexical/table@0.38.2': + dependencies: + '@lexical/clipboard': 0.38.2 + '@lexical/extension': 0.38.2 + '@lexical/utils': 0.38.2 + lexical: 0.38.2 + + '@lexical/utils@0.38.2': + dependencies: + '@lexical/list': 0.38.2 + '@lexical/selection': 0.38.2 + '@lexical/table': 0.38.2 + lexical: 0.38.2 + '@lukeed/csprng@1.1.0': {} '@microsoft/tsdoc@0.15.1': {} - '@mswjs/interceptors@0.38.6': + '@mswjs/interceptors@0.39.8': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -4677,32 +4955,39 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@nestjs/axios@4.0.0(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.8.3)(rxjs@7.8.2)': + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.6.0 + '@emnapi/runtime': 1.7.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@nestjs/axios@4.0.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.13.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - axios: 1.8.3 + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + axios: 1.13.2 rxjs: 7.8.2 - '@nestjs/cli@11.0.7(@types/node@22.13.10)': + '@nestjs/cli@11.0.10(@types/node@24.10.0)': dependencies: - '@angular-devkit/core': 19.2.8(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.8(chokidar@4.0.3) - '@angular-devkit/schematics-cli': 19.2.8(@types/node@22.13.10)(chokidar@4.0.3) - '@inquirer/prompts': 7.4.1(@types/node@22.13.10) - '@nestjs/schematics': 11.0.5(chokidar@4.0.3)(typescript@5.8.3) - ansis: 3.17.0 + '@angular-devkit/core': 19.2.15(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.15(chokidar@4.0.3) + '@angular-devkit/schematics-cli': 19.2.15(@types/node@24.10.0)(chokidar@4.0.3) + '@inquirer/prompts': 7.8.0(@types/node@24.10.0) + '@nestjs/schematics': 11.0.9(chokidar@4.0.3)(typescript@5.8.3) + ansis: 4.1.0 chokidar: 4.0.3 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.99.6) - glob: 11.0.1 + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.100.2) + glob: 11.0.3 node-emoji: 1.11.0 ora: 5.4.1 tree-kill: 1.2.2 tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.8.3 - webpack: 5.99.6 + webpack: 5.100.2 webpack-node-externals: 3.0.0 transitivePeerDependencies: - '@types/node' @@ -4710,107 +4995,118 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: file-type: 21.0.0 iterare: 1.2.1 - load-esm: 1.0.2 + load-esm: 1.0.3 reflect-metadata: 0.2.2 rxjs: 7.8.2 tslib: 2.8.1 uid: 2.0.2 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.14.1 + class-validator: 0.14.2 transitivePeerDependencies: - supports-color - '@nestjs/config@4.0.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': + '@nestjs/config@4.0.2(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) dotenv: 16.4.7 dotenv-expand: 12.0.1 lodash: 4.17.21 rxjs: 7.8.2 - '@nestjs/core@11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.2)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 reflect-metadata: 0.2.2 rxjs: 7.8.2 tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.2) + '@nestjs/platform-express': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) - '@nestjs/jwt@11.0.0(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))': + '@nestjs/jwt@11.0.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@types/jsonwebtoken': 9.0.7 + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@types/jsonwebtoken': 9.0.10 jsonwebtoken: 9.0.2 - '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)': + '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.14.1 + class-validator: 0.14.2 - '@nestjs/passport@11.0.5(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.6.0)': + '@nestjs/passport@11.0.5(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - passport: 0.6.0 + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + passport: 0.7.0 - '@nestjs/platform-express@11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.2)': + '@nestjs/platform-express@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8)': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.5 express: 5.1.0 - multer: 2.0.0 - path-to-regexp: 8.2.0 + multer: 2.0.2 + path-to-regexp: 8.3.0 tslib: 2.8.1 transitivePeerDependencies: - supports-color - '@nestjs/schematics@11.0.5(chokidar@4.0.3)(typescript@5.8.3)': + '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.8.3)': dependencies: - '@angular-devkit/core': 19.2.6(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.6(chokidar@4.0.3) - comment-json: 4.2.5 + '@angular-devkit/core': 19.2.17(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.17(chokidar@4.0.3) + comment-json: 4.4.1 jsonc-parser: 3.3.1 pluralize: 8.0.0 typescript: 5.8.3 transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.2.0(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.2)(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)': + '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)': + dependencies: + '@angular-devkit/core': 19.2.17(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.17(chokidar@4.0.3) + comment-json: 4.4.1 + jsonc-parser: 3.3.1 + pluralize: 8.0.0 + typescript: 5.9.3 + transitivePeerDependencies: + - chokidar + + '@nestjs/swagger@11.2.1(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)': dependencies: '@microsoft/tsdoc': 0.15.1 - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2) + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2) js-yaml: 4.1.0 lodash: 4.17.21 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 reflect-metadata: 0.2.2 - swagger-ui-dist: 5.21.0 + swagger-ui-dist: 5.29.4 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.14.1 + class-validator: 0.14.2 - '@nestjs/testing@11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.2)(@nestjs/platform-express@11.1.2)': + '@nestjs/testing@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8))': dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.2) + '@nestjs/platform-express': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8) '@nodelib/fs.scandir@2.1.5': dependencies: @@ -4822,7 +5118,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.16.0 + fastq: 1.19.1 '@nuxt/opencollective@0.4.1': dependencies: @@ -4843,51 +5139,72 @@ snapshots: '@open-draft/until@2.1.0': {} - '@pkgr/core@0.2.4': {} + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.2.9': {} '@polka/url@0.5.0': {} - '@prisma/client@6.8.2(prisma@6.8.2(typescript@5.8.3))(typescript@5.8.3)': + '@preact/signals-core@1.12.1': {} + + '@prisma/adapter-mariadb@6.19.0': + dependencies: + '@prisma/driver-adapter-utils': 6.19.0 + mariadb: 3.4.5 + + '@prisma/client@6.19.0(prisma@6.19.0(typescript@5.9.3))(typescript@5.9.3)': optionalDependencies: - prisma: 6.8.2(typescript@5.8.3) - typescript: 5.8.3 + prisma: 6.19.0(typescript@5.9.3) + typescript: 5.9.3 - '@prisma/config@6.8.2': + '@prisma/config@6.19.0': dependencies: - jiti: 2.4.2 + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.18.4 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + + '@prisma/debug@6.19.0': {} - '@prisma/debug@6.8.2': {} + '@prisma/driver-adapter-utils@6.19.0': + dependencies: + '@prisma/debug': 6.19.0 - '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': {} + '@prisma/engines-version@6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773': {} - '@prisma/engines@6.8.2': + '@prisma/engines@6.19.0': dependencies: - '@prisma/debug': 6.8.2 - '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/fetch-engine': 6.8.2 - '@prisma/get-platform': 6.8.2 + '@prisma/debug': 6.19.0 + '@prisma/engines-version': 6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773 + '@prisma/fetch-engine': 6.19.0 + '@prisma/get-platform': 6.19.0 - '@prisma/fetch-engine@6.8.2': + '@prisma/fetch-engine@6.19.0': dependencies: - '@prisma/debug': 6.8.2 - '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/get-platform': 6.8.2 + '@prisma/debug': 6.19.0 + '@prisma/engines-version': 6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773 + '@prisma/get-platform': 6.19.0 - '@prisma/get-platform@6.8.2': + '@prisma/get-platform@6.19.0': dependencies: - '@prisma/debug': 6.8.2 + '@prisma/debug': 6.19.0 '@scarf/scarf@1.4.0': {} - '@sinclair/typebox@0.27.8': {} + '@sinclair/typebox@0.34.41': {} - '@sinonjs/commons@3.0.0': + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 - '@sinonjs/fake-timers@10.3.0': + '@sinonjs/fake-timers@13.0.5': dependencies: - '@sinonjs/commons': 3.0.0 + '@sinonjs/commons': 3.0.1 + + '@standard-schema/spec@1.0.0': {} '@swc/helpers@0.5.17': dependencies: @@ -4895,9 +5212,9 @@ snapshots: '@tokenizer/inflate@0.2.7': dependencies: - debug: 4.4.0 + debug: 4.4.3 fflate: 0.8.2 - token-types: 6.0.0 + token-types: 6.1.1 transitivePeerDependencies: - supports-color @@ -4911,74 +5228,73 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/asn1@0.2.4': dependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 '@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.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.4 + '@types/babel__traverse': 7.28.0 - '@types/babel__generator@7.6.7': + '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.28.5 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - - '@types/babel__traverse@7.20.4': - dependencies: - '@babel/types': 7.23.6 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 - '@types/bcryptjs@3.0.0': + '@types/babel__traverse@7.28.0': dependencies: - bcryptjs: 3.0.2 + '@babel/types': 7.28.5 - '@types/body-parser@1.19.5': + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.13.10 + '@types/node': 24.10.0 '@types/connect@3.4.38': dependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 '@types/eslint-scope@3.7.7': dependencies: - '@types/eslint': 8.44.9 - '@types/estree': 1.0.6 + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 - '@types/eslint@8.44.9': + '@types/eslint@9.6.1': dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 - '@types/estree@1.0.6': {} + '@types/estree@1.0.8': {} - '@types/express-serve-static-core@5.0.6': + '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 22.13.10 - '@types/qs': 6.9.10 + '@types/node': 24.10.0 + '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 + '@types/send': 1.2.1 - '@types/express@5.0.2': + '@types/express@5.0.5': dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 5.0.6 - '@types/serve-static': 1.15.5 + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 5.1.0 + '@types/serve-static': 1.15.10 - '@types/graceful-fs@4.1.9': - dependencies: - '@types/node': 22.13.10 + '@types/geojson@7946.0.16': {} - '@types/http-errors@2.0.4': {} + '@types/http-errors@2.0.5': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -4990,38 +5306,41 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/jest@29.5.14': + '@types/jest@30.0.0': dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 + expect: 30.2.0 + pretty-format: 30.2.0 '@types/json-schema@7.0.15': {} - '@types/jsonwebtoken@9.0.5': + '@types/jsonwebtoken@9.0.10': dependencies: - '@types/node': 22.13.10 + '@types/ms': 2.1.0 + '@types/node': 24.10.0 - '@types/jsonwebtoken@9.0.7': + '@types/jsonwebtoken@9.0.5': dependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 '@types/mime@1.3.5': {} - '@types/mime@3.0.4': {} + '@types/ms@2.1.0': {} - '@types/multer@1.4.12': + '@types/multer@2.0.0': dependencies: - '@types/express': 5.0.2 + '@types/express': 5.0.5 - '@types/mysql@2.15.26': + '@types/mysql@2.15.27': dependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@types/node@22.13.10': + '@types/node@20.19.24': dependencies: - undici-types: 6.20.0 + undici-types: 6.21.0 - '@types/normalize-package-data@2.4.4': {} + '@types/node@24.10.0': + dependencies: + undici-types: 7.16.0 '@types/passport-jwt@4.0.1': dependencies: @@ -5030,118 +5349,201 @@ snapshots: '@types/passport-strategy@0.2.38': dependencies: - '@types/express': 5.0.2 + '@types/express': 5.0.5 '@types/passport': 1.0.16 '@types/passport@1.0.16': dependencies: - '@types/express': 5.0.2 + '@types/express': 5.0.5 - '@types/pdfkit@0.13.9': + '@types/pdfkit@0.17.3': dependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@types/qs@6.9.10': {} + '@types/qs@6.14.0': {} '@types/range-parser@1.2.7': {} - '@types/send@0.17.4': + '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.13.10 + '@types/node': 24.10.0 - '@types/serve-static@1.15.5': + '@types/send@1.2.1': dependencies: - '@types/http-errors': 2.0.4 - '@types/mime': 3.0.4 - '@types/node': 22.13.10 + '@types/node': 24.10.0 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 24.10.0 + '@types/send': 0.17.6 '@types/stack-utils@2.0.3': {} - '@types/validator@13.11.8': {} + '@types/validator@13.15.3': {} + + '@types/whatwg-mimetype@3.0.2': {} '@types/yargs-parser@21.0.3': {} - '@types/yargs@17.0.32': + '@types/yargs@17.0.34': dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.46.3(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.32.1 - '@typescript-eslint/type-utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.32.1 - eslint: 9.27.0(jiti@2.4.2) + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.3 + '@typescript-eslint/type-utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.3 + eslint: 9.39.1(jiti@2.6.1) graphemer: 1.4.0 - ignore: 7.0.4 + ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.32.1 - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.32.1 - debug: 4.4.0 - eslint: 9.27.0(jiti@2.4.2) - typescript: 5.8.3 + '@typescript-eslint/scope-manager': 8.46.3 + '@typescript-eslint/types': 8.46.3 + '@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.3 + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.46.3(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.46.3(typescript@5.9.3) + '@typescript-eslint/types': 8.46.3 + debug: 4.4.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.32.1': + '@typescript-eslint/scope-manager@8.46.3': dependencies: - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/visitor-keys': 8.32.1 + '@typescript-eslint/types': 8.46.3 + '@typescript-eslint/visitor-keys': 8.46.3 - '@typescript-eslint/type-utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.46.3(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - debug: 4.4.0 - eslint: 9.27.0(jiti@2.4.2) - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.46.3 + '@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.32.1': {} + '@typescript-eslint/types@8.46.3': {} - '@typescript-eslint/typescript-estree@8.32.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.46.3(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/visitor-keys': 8.32.1 - debug: 4.4.0 - fast-glob: 3.3.2 + '@typescript-eslint/project-service': 8.46.3(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.3(typescript@5.9.3) + '@typescript-eslint/types': 8.46.3 + '@typescript-eslint/visitor-keys': 8.46.3 + debug: 4.4.3 + fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + semver: 7.7.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.32.1 - '@typescript-eslint/types': 8.32.1 - '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) - eslint: 9.27.0(jiti@2.4.2) - typescript: 5.8.3 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.46.3 + '@typescript-eslint/types': 8.46.3 + '@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.32.1': + '@typescript-eslint/visitor-keys@8.46.3': + dependencies: + '@typescript-eslint/types': 8.46.3 + eslint-visitor-keys: 4.2.1 + + '@ungap/structured-clone@1.3.0': {} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': dependencies: - '@typescript-eslint/types': 8.32.1 - eslint-visitor-keys: 4.2.0 + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true '@webassemblyjs/ast@1.14.1': dependencies: @@ -5230,19 +5632,23 @@ snapshots: mime-types: 3.0.1 negotiator: 1.0.0 - acorn-jsx@5.3.2(acorn@8.14.1): + acorn-import-phases@1.0.4(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: - acorn: 8.14.1 + acorn: 8.15.0 acorn-walk@8.3.1: {} acorn@8.11.2: {} - acorn@8.14.1: {} + acorn@8.15.0: {} - ajv-formats@2.1.1(ajv@8.12.0): + ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: - ajv: 8.12.0 + ajv: 8.17.1 ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: @@ -5252,9 +5658,9 @@ snapshots: dependencies: ajv: 6.12.6 - ajv-keywords@5.1.0(ajv@8.12.0): + ajv-keywords@5.1.0(ajv@8.17.1): dependencies: - ajv: 8.12.0 + ajv: 8.17.1 fast-deep-equal: 3.1.3 ajv@6.12.6: @@ -5264,39 +5670,22 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.12.0: - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 + fast-uri: 3.1.0 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 ansi-colors@4.1.3: {} - ansi-escapes@2.0.0: {} - - ansi-escapes@3.2.0: {} - ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 - ansi-regex@3.0.1: {} - ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} - - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: @@ -5304,9 +5693,9 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} - ansis@3.17.0: {} + ansis@4.1.0: {} anymatch@3.1.3: dependencies: @@ -5335,65 +5724,65 @@ snapshots: asynckit@0.4.0: {} - axios@1.8.3: + axios@1.13.2: dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 + follow-redirects: 1.15.11 + form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - babel-jest@29.7.0(@babel/core@7.23.6): + babel-jest@30.2.0(@babel/core@7.28.5): dependencies: - '@babel/core': 7.23.6 - '@jest/transform': 29.7.0 + '@babel/core': 7.28.5 + '@jest/transform': 30.2.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-plugin-istanbul: 7.0.1 + babel-preset-jest: 30.2.0(@babel/core@7.28.5) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color - babel-plugin-istanbul@6.1.1: + babel-plugin-istanbul@7.0.1: dependencies: - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.27.1 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 + istanbul-lib-instrument: 6.0.3 test-exclude: 6.0.0 transitivePeerDependencies: - supports-color - babel-plugin-jest-hoist@29.6.3: + babel-plugin-jest-hoist@30.2.0: dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 '@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 - 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.2.0(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.5) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.5) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.5) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5) + + babel-preset-jest@30.2.0(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + babel-plugin-jest-hoist: 30.2.0 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) backoff@2.5.0: dependencies: @@ -5405,11 +5794,13 @@ snapshots: base64-js@1.5.1: {} + baseline-browser-mapping@2.8.20: {} + basic-auth@2.0.1: dependencies: safe-buffer: 5.1.2 - bcryptjs@3.0.2: {} + bcryptjs@3.0.3: {} bignumber.js@9.0.0: {} @@ -5423,39 +5814,40 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.0 + debug: 4.4.3 http-errors: 2.0.0 iconv-lite: 0.6.3 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.0 + raw-body: 3.0.1 type-is: 2.0.1 transitivePeerDependencies: - supports-color - brace-expansion@1.1.11: + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.1: + brace-expansion@2.0.2: 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.24.4: + browserslist@4.27.0: dependencies: - caniuse-lite: 1.0.30001704 - electron-to-chromium: 1.5.118 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) + baseline-browser-mapping: 2.8.20 + caniuse-lite: 1.0.30001751 + electron-to-chromium: 1.5.240 + node-releases: 2.0.26 + update-browserslist-db: 1.1.4(browserslist@4.27.0) bs-logger@0.2.6: dependencies: @@ -5480,6 +5872,21 @@ snapshots: bytes@3.1.2: {} + c12@3.1.0: + dependencies: + chokidar: 4.0.3 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 16.6.1 + exsolve: 1.0.7 + giget: 2.0.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -5496,20 +5903,14 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001704: {} + caniuse-lite@1.0.30001751: {} centra@2.7.0: dependencies: - follow-redirects: 1.15.6 + follow-redirects: 1.15.11 transitivePeerDependencies: - debug - chalk@2.4.2: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -5517,31 +5918,29 @@ snapshots: char-regex@1.0.2: {} - chardet@0.4.2: {} - - chardet@0.7.0: {} + chardet@2.1.0: {} chokidar@4.0.3: dependencies: readdirp: 4.1.2 - chrome-trace-event@1.0.3: {} + chrome-trace-event@1.0.4: {} + + ci-info@4.3.1: {} - ci-info@3.9.0: {} + citty@0.1.6: + dependencies: + consola: 3.4.2 - cjs-module-lexer@1.2.3: {} + cjs-module-lexer@2.1.0: {} 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 - - cli-cursor@2.1.0: + class-validator@0.14.2: dependencies: - restore-cursor: 2.0.0 + '@types/validator': 13.15.3 + libphonenumber-js: 1.12.24 + validator: 13.15.15 cli-cursor@3.1.0: dependencies: @@ -5552,15 +5951,8 @@ snapshots: cli-table3@0.6.5: dependencies: string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - - cli-truncate@1.1.0: - dependencies: - slice-ansi: 1.0.0 - string-width: 2.1.1 - - cli-width@2.2.1: {} + optionalDependencies: + '@colors/colors': 1.5.0 cli-width@4.1.0: {} @@ -5576,55 +5968,43 @@ snapshots: co@4.6.0: {} - collect-v8-coverage@1.0.2: {} - - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 + collect-v8-coverage@1.0.3: {} color-convert@2.0.1: dependencies: color-name: 1.1.4 - color-name@1.1.3: {} - color-name@1.1.4: {} - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 + commander@13.1.0: {} + commander@2.20.3: {} commander@4.1.1: {} - comment-json@4.2.5: + comment-json@4.4.1: dependencies: array-timsort: 1.0.3 core-util-is: 1.0.3 esprima: 4.0.1 - has-own-prop: 2.0.0 - repeat-string: 1.6.1 + + component-type@2.0.0: {} concat-map@0.0.1: {} - concat-stream@1.6.2: + concat-stream@2.0.0: dependencies: buffer-from: 1.1.2 inherits: 2.0.4 - readable-stream: 2.3.8 + readable-stream: 3.6.2 typedarray: 0.0.6 + confbox@0.2.2: {} + consola@3.4.2: {} content-disposition@1.0.0: @@ -5635,9 +6015,11 @@ snapshots: convert-source-map@2.0.0: {} + cookie-lite@0.0.1: {} + cookie-signature@1.2.2: {} - cookie@0.7.1: {} + cookie@0.7.2: {} core-util-is@1.0.2: {} @@ -5652,36 +6034,15 @@ snapshots: cosmiconfig@8.3.6(typescript@5.8.3): dependencies: - import-fresh: 3.3.0 + import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: typescript: 5.8.3 - create-jest@29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - create-require@1.1.1: {} - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -5690,47 +6051,48 @@ snapshots: crypto-js@4.2.0: {} - cz-emoji@1.3.2-canary.2: + debug@4.4.0: dependencies: - cli-truncate: 1.1.0 - find-up: 5.0.0 - fuse.js: 3.6.1 - homedir: 0.6.0 - inquirer-autocomplete-prompt: 0.12.2 - inquirer-maxlength-input-prompt: 1.0.2 - pad: 2.3.0 - prettier: 1.19.1 - read-pkg-up: 7.0.1 - wrap-ansi: 7.0.0 + ms: 2.1.3 - debug@4.4.0: + debug@4.4.1: + dependencies: + ms: 2.1.3 + + debug@4.4.3: dependencies: ms: 2.1.3 - dedent@1.5.1: {} + dedent@1.7.0: {} deep-is@0.1.4: {} deep-override@1.0.2: {} + deepmerge-ts@7.1.5: {} + deepmerge@4.3.1: {} defaults@1.0.4: dependencies: clone: 1.0.4 + defu@6.1.4: {} + delayed-stream@1.0.0: {} + denque@2.1.0: {} + depd@2.0.0: {} - detect-libc@2.0.3: {} + destr@2.0.5: {} + + detect-libc@2.1.2: {} detect-newline@3.1.0: {} dfa@1.2.0: {} - diff-sequences@29.6.3: {} - diff@4.0.2: {} dotenv-expand@12.0.1: @@ -5739,6 +6101,8 @@ snapshots: dotenv@16.4.7: {} + dotenv@16.6.1: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -5753,11 +6117,12 @@ snapshots: ee-first@1.1.1: {} - ejs@3.1.10: + effect@3.18.4: dependencies: - jake: 10.9.2 + '@standard-schema/spec': 1.0.0 + fast-check: 3.23.2 - electron-to-chromium@1.5.118: {} + electron-to-chromium@1.5.240: {} emittery@0.13.1: {} @@ -5765,17 +6130,20 @@ snapshots: emoji-regex@9.2.2: {} + empathic@2.0.0: {} + encodeurl@2.0.0: {} - enhanced-resolve@5.18.1: + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.3.0 - env-cmd@10.1.0: + env-cmd@11.0.0: dependencies: - commander: 4.1.1 - cross-spawn: 7.0.3 + '@commander-js/extra-typings': 13.1.0(commander@13.1.0) + commander: 13.1.0 + cross-spawn: 7.0.6 error-ex@1.3.2: dependencies: @@ -5785,101 +6153,105 @@ snapshots: es-errors@1.3.0: {} - es-module-lexer@1.4.1: {} + es-module-lexer@1.7.0: {} es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + escalade@3.2.0: {} escape-html@1.0.3: {} - escape-string-regexp@1.0.5: {} - escape-string-regexp@2.0.0: {} escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)): + eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)): dependencies: - eslint: 9.27.0(jiti@2.4.2) + eslint: 9.39.1(jiti@2.6.1) - eslint-plugin-prettier@5.4.0(@types/eslint@8.44.9)(eslint-config-prettier@10.1.5(eslint@9.27.0(jiti@2.4.2)))(eslint@9.27.0(jiti@2.4.2))(prettier@3.5.3): + eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2): dependencies: - eslint: 9.27.0(jiti@2.4.2) - prettier: 3.5.3 + eslint: 9.39.1(jiti@2.6.1) + prettier: 3.6.2 prettier-linter-helpers: 1.0.0 - synckit: 0.11.6 + synckit: 0.11.11 optionalDependencies: - '@types/eslint': 8.44.9 - eslint-config-prettier: 10.1.5(eslint@9.27.0(jiti@2.4.2)) + '@types/eslint': 9.6.1 + eslint-config-prettier: 10.1.8(eslint@9.39.1(jiti@2.6.1)) eslint-scope@5.1.1: dependencies: esrecurse: 4.3.0 estraverse: 4.3.0 - eslint-scope@8.3.0: + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} - eslint@9.27.0(jiti@2.4.2): + eslint@9.39.1(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.27.0(jiti@2.4.2)) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.0 - '@eslint/config-helpers': 0.2.2 - '@eslint/core': 0.14.0 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.27.0 - '@eslint/plugin-kit': 0.3.1 - '@humanfs/node': 0.16.6 + '@eslint/js': 9.39.1 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 + '@types/estree': 1.0.8 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0 + debug: 4.4.3 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 - esquery: 1.5.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - ignore: 5.3.0 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.3 + optionator: 0.9.4 optionalDependencies: - jiti: 2.4.2 + jiti: 2.6.1 transitivePeerDependencies: - supports-color - espree@10.3.0: + espree@10.4.0: dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) - eslint-visitor-keys: 4.2.0 + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 esprima@4.0.1: {} - esquery@1.5.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -5901,7 +6273,7 @@ snapshots: execa@5.1.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 get-stream: 6.0.1 human-signals: 2.1.0 is-stream: 2.0.1 @@ -5911,15 +6283,16 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - exit@0.1.2: {} + exit-x@0.2.2: {} - expect@29.7.0: + expect@30.2.0: dependencies: - '@jest/expect-utils': 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 + '@jest/expect-utils': 30.2.0 + '@jest/get-type': 30.1.0 + jest-matcher-utils: 30.2.0 + jest-message-util: 30.2.0 + jest-mock: 30.2.0 + jest-util: 30.2.0 express@5.1.0: dependencies: @@ -5927,9 +6300,9 @@ snapshots: body-parser: 2.2.0 content-disposition: 1.0.0 content-type: 1.0.5 - cookie: 0.7.1 + cookie: 0.7.2 cookie-signature: 1.2.2 - debug: 4.4.0 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -5947,37 +6320,31 @@ snapshots: router: 2.2.0 send: 1.2.0 serve-static: 2.2.0 - statuses: 2.0.1 + statuses: 2.0.2 type-is: 2.0.1 vary: 1.1.2 transitivePeerDependencies: - supports-color - external-editor@2.2.0: - dependencies: - chardet: 0.4.2 - iconv-lite: 0.4.24 - tmp: 0.0.33 - - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 + exsolve@1.0.7: {} extsprintf@1.4.1: {} + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} - fast-glob@3.3.2: + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} @@ -5985,15 +6352,15 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.0.6: {} + fast-uri@3.1.0: {} - fast-xml-parser@5.2.3: + fast-xml-parser@5.3.1: dependencies: strnum: 2.1.1 - fastq@1.16.0: + fastq@1.19.1: dependencies: - reusify: 1.0.4 + reusify: 1.1.0 fb-watchman@2.0.2: dependencies: @@ -6001,48 +6368,31 @@ snapshots: fflate@0.8.2: {} - figures@2.0.0: - dependencies: - escape-string-regexp: 1.0.5 - file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 - file-type@20.5.0: - dependencies: - '@tokenizer/inflate': 0.2.7 - strtok3: 10.2.2 - token-types: 6.0.0 - uint8array-extras: 1.4.0 - transitivePeerDependencies: - - supports-color - file-type@21.0.0: dependencies: '@tokenizer/inflate': 0.2.7 - strtok3: 10.2.2 - token-types: 6.0.0 - uint8array-extras: 1.4.0 + strtok3: 10.3.4 + token-types: 6.1.1 + uint8array-extras: 1.5.0 transitivePeerDependencies: - supports-color - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 finalhandler@2.1.0: dependencies: - debug: 4.4.0 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 - statuses: 2.0.1 + statuses: 2.0.2 transitivePeerDependencies: - supports-color @@ -6058,10 +6408,12 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.2.9 + flatted: 3.3.3 keyv: 4.5.4 - flatted@3.2.9: {} + flatted@3.3.3: {} + + follow-redirects@1.15.11: {} follow-redirects@1.15.6: {} @@ -6077,14 +6429,14 @@ snapshots: unicode-properties: 1.4.1 unicode-trie: 2.0.0 - foreground-child@3.1.1: + foreground-child@3.3.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.99.6): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.100.2): dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.27.1 chalk: 4.1.2 chokidar: 4.0.3 cosmiconfig: 8.3.6(typescript@5.8.3) @@ -6094,10 +6446,10 @@ snapshots: minimatch: 3.1.2 node-abort-controller: 3.1.1 schema-utils: 3.3.0 - semver: 7.7.1 - tapable: 2.2.1 + semver: 7.7.3 + tapable: 2.3.0 typescript: 5.8.3 - webpack: 5.99.6 + webpack: 5.100.2 form-data-lite@1.0.3: dependencies: @@ -6105,10 +6457,12 @@ snapshots: combined-stream: 1.0.8 mime-lite: 1.0.3 - form-data@4.0.0: + form-data@4.0.4: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 forwarded@0.2.0: {} @@ -6118,10 +6472,10 @@ snapshots: fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 - fs-monkey@1.0.5: {} + fs-monkey@1.1.0: {} fs.realpath@1.0.0: {} @@ -6130,8 +6484,6 @@ snapshots: function-bind@1.1.2: {} - fuse.js@3.6.1: {} - gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -6158,6 +6510,15 @@ snapshots: get-stream@6.0.1: {} + giget@2.0.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.7 + nypm: 0.6.2 + pathe: 2.0.3 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -6168,11 +6529,20 @@ snapshots: glob-to-regexp@0.4.1: {} - glob@11.0.1: + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@11.0.3: dependencies: - foreground-child: 3.1.1 + foreground-child: 3.3.1 jackspeak: 4.1.1 - minimatch: 10.0.1 + minimatch: 10.0.3 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 2.0.0 @@ -6186,11 +6556,9 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 - globals@11.12.0: {} - globals@14.0.0: {} - globals@16.2.0: {} + globals@16.5.0: {} gopd@1.2.0: {} @@ -6198,17 +6566,28 @@ snapshots: graphemer@1.4.0: {} - has-flag@3.0.0: {} + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + happy-dom@20.0.10: + dependencies: + '@types/node': 20.19.24 + '@types/whatwg-mimetype': 3.0.2 + whatwg-mimetype: 3.0.0 has-flag@4.0.0: {} - has-own-prop@2.0.0: {} - has-symbols@1.1.0: {} - hasown@2.0.0: + has-tostringtag@1.0.2: dependencies: - function-bind: 1.1.2 + has-symbols: 1.1.0 hasown@2.0.2: dependencies: @@ -6216,10 +6595,6 @@ snapshots: he@1.2.0: {} - homedir@0.6.0: {} - - hosted-git-info@2.8.9: {} - html-encoding-sniffer@3.0.0: dependencies: whatwg-encoding: 2.0.0 @@ -6263,26 +6638,26 @@ snapshots: human-signals@2.1.0: {} - iconv-lite@0.4.24: + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.6.3: + iconv-lite@0.7.0: dependencies: safer-buffer: 2.1.2 ieee754@1.2.1: {} - ignore@5.3.0: {} + ignore@5.3.2: {} - ignore@7.0.4: {} + ignore@7.0.5: {} - import-fresh@3.3.0: + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - import-local@3.1.0: + import-local@3.2.0: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 @@ -6296,69 +6671,12 @@ snapshots: inherits@2.0.4: {} - inquirer-autocomplete-prompt@0.12.2: - dependencies: - ansi-escapes: 3.2.0 - chalk: 2.4.2 - figures: 2.0.0 - inquirer: 3.2.0 - run-async: 2.4.1 - - inquirer-maxlength-input-prompt@1.0.2: - dependencies: - chalk: 2.4.2 - inquirer: 5.2.0 - lodash.invoke: 4.5.2 - lodash.isfunction: 3.0.9 - lodash.partialright: 4.2.1 - - inquirer@3.2.0: - dependencies: - ansi-escapes: 2.0.0 - chalk: 2.4.2 - cli-cursor: 2.1.0 - cli-width: 2.2.1 - external-editor: 2.2.0 - figures: 2.0.0 - lodash: 4.17.21 - mute-stream: 0.0.7 - run-async: 2.4.1 - rx-lite: 4.0.8 - rx-lite-aggregates: 4.0.8 - string-width: 2.1.1 - strip-ansi: 4.0.0 - through: 2.3.8 - - inquirer@5.2.0: - dependencies: - ansi-escapes: 3.2.0 - chalk: 2.4.2 - cli-cursor: 2.1.0 - cli-width: 2.2.1 - external-editor: 2.2.0 - figures: 2.0.0 - lodash: 4.17.21 - mute-stream: 0.0.7 - run-async: 2.4.1 - rxjs: 5.5.12 - string-width: 2.1.1 - strip-ansi: 4.0.0 - through: 2.3.8 - ipaddr.js@1.9.1: {} is-arrayish@0.2.1: {} - is-arrayish@0.3.2: {} - - is-core-module@2.13.1: - dependencies: - hasown: 2.0.0 - is-extglob@2.1.1: {} - is-fullwidth-code-point@2.0.0: {} - is-fullwidth-code-point@3.0.0: {} is-generator-fn@2.1.0: {} @@ -6385,23 +6703,13 @@ snapshots: istanbul-lib-coverage@3.2.2: {} - istanbul-lib-instrument@5.2.1: - dependencies: - '@babel/core': 7.23.6 - '@babel/parser': 7.23.6 - '@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.28.5 + '@babel/parser': 7.28.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.7.1 + semver: 7.7.3 transitivePeerDependencies: - supports-color @@ -6411,348 +6719,350 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: + istanbul-lib-source-maps@5.0.6: dependencies: - debug: 4.4.0 + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 transitivePeerDependencies: - supports-color - istanbul-reports@3.1.6: + istanbul-reports@3.2.0: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 iterare@1.2.1: {} - jackspeak@4.1.1: + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 - jake@10.9.2: + jackspeak@4.1.1: dependencies: - async: 3.2.6 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 + '@isaacs/cliui': 8.0.2 - jest-changed-files@29.7.0: + jest-changed-files@30.2.0: dependencies: execa: 5.1.1 - jest-util: 29.7.0 + jest-util: 30.2.0 p-limit: 3.1.0 - jest-circus@29.7.0: + jest-circus@30.2.0: dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.13.10 + '@jest/environment': 30.2.0 + '@jest/expect': 30.2.0 + '@jest/test-result': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 chalk: 4.1.2 co: 4.6.0 - dedent: 1.5.1 + dedent: 1.7.0 is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 + jest-each: 30.2.0 + jest-matcher-utils: 30.2.0 + jest-message-util: 30.2.0 + jest-runtime: 30.2.0 + jest-snapshot: 30.2.0 + jest-util: 30.2.0 p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.0.4 + pretty-format: 30.2.0 + pure-rand: 7.0.1 slash: 3.0.0 stack-utils: 2.0.6 transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)): + jest-cli@30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 + '@jest/core': 30.2.0(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)) + '@jest/test-result': 30.2.0 + '@jest/types': 30.2.0 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) - exit: 0.1.2 - import-local: 3.1.0 - jest-config: 29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) - jest-util: 29.7.0 - jest-validate: 29.7.0 + exit-x: 0.2.2 + import-local: 3.2.0 + jest-config: 30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)) + jest-util: 30.2.0 + jest-validate: 30.2.0 yargs: 17.7.2 transitivePeerDependencies: - '@types/node' - babel-plugin-macros + - esbuild-register - supports-color - ts-node - jest-config@29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)): + jest-config@30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)): dependencies: - '@babel/core': 7.23.6 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.23.6) + '@babel/core': 7.28.5 + '@jest/get-type': 30.1.0 + '@jest/pattern': 30.0.1 + '@jest/test-sequencer': 30.2.0 + '@jest/types': 30.2.0 + babel-jest: 30.2.0(@babel/core@7.28.5) chalk: 4.1.2 - ci-info: 3.9.0 + ci-info: 4.3.1 deepmerge: 4.3.1 - glob: 7.2.3 + glob: 10.4.5 graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.5 + jest-circus: 30.2.0 + jest-docblock: 30.2.0 + jest-environment-node: 30.2.0 + jest-regex-util: 30.0.1 + jest-resolve: 30.2.0 + jest-runner: 30.2.0 + jest-util: 30.2.0 + jest-validate: 30.2.0 + micromatch: 4.0.8 parse-json: 5.2.0 - pretty-format: 29.7.0 + pretty-format: 30.2.0 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.13.10 - ts-node: 10.9.2(@types/node@22.13.10)(typescript@5.8.3) + '@types/node': 24.10.0 + ts-node: 10.9.2(@types/node@24.10.0)(typescript@5.9.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-diff@29.7.0: + jest-diff@30.2.0: dependencies: + '@jest/diff-sequences': 30.0.1 + '@jest/get-type': 30.1.0 chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + pretty-format: 30.2.0 - jest-docblock@29.7.0: + jest-docblock@30.2.0: dependencies: detect-newline: 3.1.0 - jest-each@29.7.0: + jest-each@30.2.0: dependencies: - '@jest/types': 29.6.3 + '@jest/get-type': 30.1.0 + '@jest/types': 30.2.0 chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 + jest-util: 30.2.0 + pretty-format: 30.2.0 - jest-environment-node@29.7.0: + jest-environment-node@30.2.0: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.13.10 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - jest-get-type@29.6.3: {} + '@jest/environment': 30.2.0 + '@jest/fake-timers': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 + jest-mock: 30.2.0 + jest-util: 30.2.0 + jest-validate: 30.2.0 - jest-haste-map@29.7.0: + jest-haste-map@30.2.0: dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 22.13.10 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 - micromatch: 4.0.5 + jest-regex-util: 30.0.1 + jest-util: 30.2.0 + jest-worker: 30.2.0 + micromatch: 4.0.8 walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 - jest-leak-detector@29.7.0: + jest-leak-detector@30.2.0: dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + '@jest/get-type': 30.1.0 + pretty-format: 30.2.0 - jest-matcher-utils@29.7.0: + jest-matcher-utils@30.2.0: dependencies: + '@jest/get-type': 30.1.0 chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + jest-diff: 30.2.0 + pretty-format: 30.2.0 - jest-message-util@29.7.0: + jest-message-util@30.2.0: dependencies: - '@babel/code-frame': 7.23.5 - '@jest/types': 29.6.3 + '@babel/code-frame': 7.27.1 + '@jest/types': 30.2.0 '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.7.0 + micromatch: 4.0.8 + pretty-format: 30.2.0 slash: 3.0.0 stack-utils: 2.0.6 - jest-mock@29.7.0: + jest-mock@30.2.0: dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.13.10 - jest-util: 29.7.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 + jest-util: 30.2.0 - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + jest-pnp-resolver@1.2.3(jest-resolve@30.2.0): optionalDependencies: - jest-resolve: 29.7.0 + jest-resolve: 30.2.0 - jest-regex-util@29.6.3: {} + jest-regex-util@30.0.1: {} - jest-resolve-dependencies@29.7.0: + jest-resolve-dependencies@30.2.0: dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 + jest-regex-util: 30.0.1 + jest-snapshot: 30.2.0 transitivePeerDependencies: - supports-color - jest-resolve@29.7.0: + jest-resolve@30.2.0: dependencies: chalk: 4.1.2 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.8 - resolve.exports: 2.0.2 + jest-haste-map: 30.2.0 + jest-pnp-resolver: 1.2.3(jest-resolve@30.2.0) + jest-util: 30.2.0 + jest-validate: 30.2.0 slash: 3.0.0 + unrs-resolver: 1.11.1 - jest-runner@29.7.0: + jest-runner@30.2.0: dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.13.10 + '@jest/console': 30.2.0 + '@jest/environment': 30.2.0 + '@jest/test-result': 30.2.0 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 chalk: 4.1.2 emittery: 0.13.1 + exit-x: 0.2.2 graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 + jest-docblock: 30.2.0 + jest-environment-node: 30.2.0 + jest-haste-map: 30.2.0 + jest-leak-detector: 30.2.0 + jest-message-util: 30.2.0 + jest-resolve: 30.2.0 + jest-runtime: 30.2.0 + jest-util: 30.2.0 + jest-watcher: 30.2.0 + jest-worker: 30.2.0 p-limit: 3.1.0 source-map-support: 0.5.13 transitivePeerDependencies: - supports-color - jest-runtime@29.7.0: + jest-runtime@30.2.0: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.13.10 + '@jest/environment': 30.2.0 + '@jest/fake-timers': 30.2.0 + '@jest/globals': 30.2.0 + '@jest/source-map': 30.0.1 + '@jest/test-result': 30.2.0 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 chalk: 4.1.2 - cjs-module-lexer: 1.2.3 - collect-v8-coverage: 1.0.2 - glob: 7.2.3 + cjs-module-lexer: 2.1.0 + collect-v8-coverage: 1.0.3 + glob: 10.4.5 graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 + jest-haste-map: 30.2.0 + jest-message-util: 30.2.0 + jest-mock: 30.2.0 + jest-regex-util: 30.0.1 + jest-resolve: 30.2.0 + jest-snapshot: 30.2.0 + jest-util: 30.2.0 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - 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 - '@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) + jest-snapshot@30.2.0: + dependencies: + '@babel/core': 7.28.5 + '@babel/generator': 7.28.5 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.5 + '@jest/expect-utils': 30.2.0 + '@jest/get-type': 30.1.0 + '@jest/snapshot-utils': 30.2.0 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) chalk: 4.1.2 - expect: 29.7.0 + expect: 30.2.0 graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.7.1 + jest-diff: 30.2.0 + jest-matcher-utils: 30.2.0 + jest-message-util: 30.2.0 + jest-util: 30.2.0 + pretty-format: 30.2.0 + semver: 7.7.3 + synckit: 0.11.11 transitivePeerDependencies: - supports-color - jest-util@29.7.0: + jest-util@30.2.0: dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.13.10 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 chalk: 4.1.2 - ci-info: 3.9.0 + ci-info: 4.3.1 graceful-fs: 4.2.11 - picomatch: 2.3.1 + picomatch: 4.0.3 - jest-validate@29.7.0: + jest-validate@30.2.0: dependencies: - '@jest/types': 29.6.3 + '@jest/get-type': 30.1.0 + '@jest/types': 30.2.0 camelcase: 6.3.0 chalk: 4.1.2 - jest-get-type: 29.6.3 leven: 3.1.0 - pretty-format: 29.7.0 + pretty-format: 30.2.0 - jest-watcher@29.7.0: + jest-watcher@30.2.0: dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.13.10 + '@jest/test-result': 30.2.0 + '@jest/types': 30.2.0 + '@types/node': 24.10.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 - jest-util: 29.7.0 + jest-util: 30.2.0 string-length: 4.0.2 jest-worker@27.5.1: dependencies: - '@types/node': 22.13.10 + '@types/node': 24.10.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest-worker@29.7.0: + jest-worker@30.2.0: dependencies: - '@types/node': 22.13.10 - jest-util: 29.7.0 + '@types/node': 24.10.0 + '@ungap/structured-clone': 1.3.0 + jest-util: 30.2.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)): + jest@30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) - '@jest/types': 29.6.3 - import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) + '@jest/core': 30.2.0(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)) + '@jest/types': 30.2.0 + import-local: 3.2.0 + jest-cli: 30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros + - esbuild-register - supports-color - ts-node - jiti@2.4.2: {} + jiti@2.6.1: {} jpeg-exif@1.1.4: {} @@ -6767,7 +7077,7 @@ snapshots: dependencies: argparse: 2.0.1 - jsesc@2.5.2: {} + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -6787,7 +7097,7 @@ snapshots: jsonc-parser@3.3.1: {} - jsonfile@6.1.0: + jsonfile@6.2.0: dependencies: universalify: 2.0.1 optionalDependencies: @@ -6821,8 +7131,6 @@ snapshots: dependencies: json-buffer: 3.0.1 - kleur@3.0.3: {} - klona@2.0.6: {} ldap-filter@0.3.3: @@ -6845,14 +7153,14 @@ snapshots: vasync: 2.2.1 verror: 1.10.1 - ldapts@7.3.1: + ldapts@8.0.9: dependencies: '@types/asn1': 0.2.4 asn1: 0.2.6 - debug: 4.4.0 + debug: 4.4.1 strict-event-emitter-types: 2.0.0 - uuid: 11.0.5 - whatwg-url: 14.1.1 + uuid: 11.1.0 + whatwg-url: 14.2.0 transitivePeerDependencies: - supports-color @@ -6863,9 +7171,9 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - libphonenumber-js@1.10.54: {} + lexical@0.38.2: {} - lightcookie@1.0.25: {} + libphonenumber-js@1.12.24: {} linebreak@1.1.0: dependencies: @@ -6874,9 +7182,9 @@ snapshots: lines-and-columns@1.2.4: {} - load-esm@1.0.2: {} + load-esm@1.0.3: {} - loader-runner@4.3.0: {} + loader-runner@4.3.1: {} locate-path@5.0.0: dependencies: @@ -6892,8 +7200,6 @@ snapshots: lodash.includes@4.3.0: {} - lodash.invoke@4.5.2: {} - lodash.isboolean@3.0.3: {} lodash.isfunction@3.0.9: {} @@ -6916,8 +7222,6 @@ snapshots: lodash.once@4.1.1: {} - lodash.partialright@4.2.1: {} - lodash.uniq@4.5.0: {} lodash@4.17.21: {} @@ -6927,7 +7231,9 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 - lru-cache@11.1.0: {} + lru-cache@10.4.3: {} + + lru-cache@11.2.2: {} lru-cache@5.1.1: dependencies: @@ -6939,11 +7245,11 @@ snapshots: magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 make-dir@4.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.3 make-error@1.3.6: {} @@ -6951,6 +7257,14 @@ snapshots: dependencies: tmpl: 1.0.5 + mariadb@3.4.5: + dependencies: + '@types/geojson': 7946.0.16 + '@types/node': 24.10.0 + denque: 2.1.0 + iconv-lite: 0.6.3 + lru-cache: 10.4.3 + matchit@1.1.0: dependencies: '@arr/every': 1.0.1 @@ -6963,7 +7277,7 @@ snapshots: memfs@3.5.3: dependencies: - fs-monkey: 1.0.5 + fs-monkey: 1.1.0 merge-descriptors@2.0.0: {} @@ -6971,9 +7285,9 @@ snapshots: merge2@1.4.1: {} - micromatch@4.0.5: + micromatch@4.0.8: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 mime-db@1.52.0: {} @@ -6992,25 +7306,19 @@ snapshots: mime@1.6.0: {} - mimic-fn@1.2.0: {} - mimic-fn@2.1.0: {} - minimatch@10.0.1: + minimatch@10.0.3: dependencies: - brace-expansion: 2.0.1 + '@isaacs/brace-expansion': 5.0.0 minimatch@3.1.2: dependencies: - brace-expansion: 1.1.11 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.1 + brace-expansion: 1.1.12 minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist@1.2.8: {} @@ -7022,28 +7330,16 @@ snapshots: ms@2.1.3: {} - multer@1.4.5-lts.1: - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 1.6.2 - mkdirp: 0.5.6 - object-assign: 4.1.1 - type-is: 1.6.18 - xtend: 4.0.2 - - multer@2.0.0: + multer@2.0.2: dependencies: append-field: 1.0.0 busboy: 1.6.0 - concat-stream: 1.6.2 + concat-stream: 2.0.0 mkdirp: 0.5.6 object-assign: 4.1.1 type-is: 1.6.18 xtend: 4.0.2 - mute-stream@0.0.7: {} - mute-stream@2.0.0: {} mysql@2.18.1: @@ -7053,21 +7349,23 @@ snapshots: safe-buffer: 5.1.2 sqlstring: 2.3.1 + napi-postinstall@0.3.4: {} + natural-compare@1.4.0: {} negotiator@1.0.0: {} neo-async@2.6.2: {} - nestjs-spelunker@1.3.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.2): + nestjs-spelunker@1.3.2(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2)): dependencies: - '@nestjs/common': 11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.2(@nestjs/common@11.1.2(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.8(@nestjs/common@11.1.8(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.8)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@ogma/styler': 1.1.0 - nock@14.0.4: + nock@14.0.10: dependencies: - '@mswjs/interceptors': 0.38.6 + '@mswjs/interceptors': 0.39.8 json-stringify-safe: 5.0.1 propagate: 2.0.1 @@ -7077,16 +7375,11 @@ snapshots: dependencies: lodash: 4.17.21 - node-int64@0.4.0: {} + node-fetch-native@1.6.7: {} - node-releases@2.0.19: {} + node-int64@0.4.0: {} - normalize-package-data@2.5.0: - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.8 - semver: 5.7.2 - validate-npm-package-license: 3.0.4 + node-releases@2.0.26: {} normalize-path@3.0.0: {} @@ -7094,10 +7387,20 @@ snapshots: dependencies: path-key: 3.1.1 + nypm@0.6.2: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 2.3.0 + tinyexec: 1.0.2 + object-assign@4.1.1: {} object-inspect@1.13.4: {} + ohash@2.0.11: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -7106,10 +7409,6 @@ snapshots: dependencies: wrappy: 1.0.2 - onetime@2.0.1: - dependencies: - mimic-fn: 1.2.0 - onetime@5.1.2: dependencies: mimic-fn: 2.1.0 @@ -7120,14 +7419,14 @@ snapshots: opener@1.5.2: {} - 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: @@ -7141,8 +7440,6 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - os-tmpdir@1.0.2: {} - outvariant@1.4.3: {} p-limit@2.3.0: @@ -7167,14 +7464,15 @@ snapshots: pactum-matchers@1.1.7: {} - pactum@3.7.6: + pactum@3.8.0: dependencies: '@exodus/schemasafe': 1.3.0 + component-type: 2.0.0 + cookie-lite: 0.0.1 deep-override: 1.0.2 form-data-lite: 1.0.3 json-query: 2.2.2 klona: 2.0.6 - lightcookie: 1.0.25 openapi-fuzzer-core: 1.0.6 pactum-matchers: 1.1.7 parse-graphql: 1.0.0 @@ -7183,10 +7481,6 @@ snapshots: transitivePeerDependencies: - debug - pad@2.3.0: - dependencies: - wcwidth: 1.0.1 - pako@0.2.9: {} parent-module@1.0.1: @@ -7197,7 +7491,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.27.1 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -7211,7 +7505,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 @@ -7223,20 +7517,25 @@ snapshots: path-key@3.1.1: {} - path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 path-scurry@2.0.0: dependencies: - lru-cache: 11.1.0 + lru-cache: 11.2.2 minipass: 7.1.2 - path-to-regexp@8.2.0: {} + path-to-regexp@8.3.0: {} path-type@4.0.0: {} + pathe@2.0.3: {} + pause@0.0.1: {} - pdfkit@0.16.0: + pdfkit@0.17.2: dependencies: crypto-js: 4.2.0 fontkit: 2.0.4 @@ -7244,7 +7543,7 @@ snapshots: linebreak: 1.1.0 png-js: 1.0.0 - peek-readable@7.0.0: {} + perfect-debounce@1.0.0: {} phin@3.7.1: dependencies: @@ -7258,12 +7557,20 @@ snapshots: picomatch@4.0.2: {} - pirates@4.0.6: {} + picomatch@4.0.3: {} + + pirates@4.0.7: {} pkg-dir@4.2.0: dependencies: find-up: 4.1.0 + pkg-types@2.3.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.7 + pathe: 2.0.3 + pluralize@8.0.0: {} png-js@1.0.0: {} @@ -7288,29 +7595,26 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier@1.19.1: {} - - prettier@3.5.3: {} + prettier@3.6.2: {} - pretty-format@29.7.0: + pretty-format@30.2.0: dependencies: - '@jest/schemas': 29.6.3 + '@jest/schemas': 30.0.5 ansi-styles: 5.2.0 - react-is: 18.2.0 + react-is: 18.3.1 - prisma@6.8.2(typescript@5.8.3): + prisma@6.19.0(typescript@5.9.3): dependencies: - '@prisma/config': 6.8.2 - '@prisma/engines': 6.8.2 + '@prisma/config': 6.19.0 + '@prisma/engines': 6.19.0 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 + transitivePeerDependencies: + - magicast - process-nextick-args@2.0.1: {} + prismjs@1.30.0: {} - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 + process-nextick-args@2.0.1: {} propagate@2.0.1: {} @@ -7323,7 +7627,9 @@ snapshots: punycode@2.3.1: {} - pure-rand@6.0.4: {} + pure-rand@6.1.0: {} + + pure-rand@7.0.1: {} qs@6.13.0: dependencies: @@ -7341,27 +7647,19 @@ snapshots: range-parser@1.2.1: {} - raw-body@3.0.0: + raw-body@3.0.1: dependencies: bytes: 3.1.2 http-errors: 2.0.0 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 unpipe: 1.0.0 - react-is@18.2.0: {} - - read-pkg-up@7.0.1: + rc9@2.1.2: dependencies: - find-up: 4.1.0 - read-pkg: 5.2.0 - type-fest: 0.8.1 + defu: 6.1.4 + destr: 2.0.5 - read-pkg@5.2.0: - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 2.5.0 - parse-json: 5.2.0 - type-fest: 0.6.0 + react-is@18.3.1: {} readable-stream@2.3.7: dependencies: @@ -7373,16 +7671,6 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -7393,8 +7681,6 @@ snapshots: reflect-metadata@0.2.2: {} - repeat-string@1.6.1: {} - require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -7409,19 +7695,6 @@ snapshots: resolve-from@5.0.0: {} - resolve.exports@2.0.2: {} - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - restore-cursor@2.0.0: - dependencies: - onetime: 2.0.1 - signal-exit: 3.0.7 - restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -7429,34 +7702,22 @@ snapshots: restructure@3.0.2: {} - reusify@1.0.4: {} + reusify@1.1.0: {} router@2.2.0: dependencies: - debug: 4.4.0 + debug: 4.4.3 depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 transitivePeerDependencies: - supports-color - run-async@2.4.1: {} - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - rx-lite-aggregates@4.0.8: - dependencies: - rx-lite: 4.0.8 - - rx-lite@4.0.8: {} - - rxjs@5.5.12: - dependencies: - symbol-observable: 1.0.1 - rxjs@7.8.1: dependencies: tslib: 2.8.1 @@ -7477,28 +7738,26 @@ snapshots: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - schema-utils@4.3.0: + schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.12.0 - ajv-formats: 2.1.1(ajv@8.12.0) - ajv-keywords: 5.1.0(ajv@8.12.0) + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) secure-compare@3.0.1: {} - semver@5.7.2: {} - semver@6.3.1: {} semver@7.5.4: dependencies: lru-cache: 6.0.0 - semver@7.7.1: {} + semver@7.7.3: {} send@1.2.0: dependencies: - debug: 4.4.0 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -7508,7 +7767,7 @@ snapshots: ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 - statuses: 2.0.1 + statuses: 2.0.2 transitivePeerDependencies: - supports-color @@ -7527,31 +7786,36 @@ snapshots: setprototypeof@1.2.0: {} - sharp@0.33.5: + sharp@0.34.5: dependencies: - color: 4.2.3 - detect-libc: 2.0.3 - semver: 7.7.1 + '@img/colour': 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.3 optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.5 - '@img/sharp-darwin-x64': 0.33.5 - '@img/sharp-libvips-darwin-arm64': 1.0.4 - '@img/sharp-libvips-darwin-x64': 1.0.4 - '@img/sharp-libvips-linux-arm': 1.0.5 - '@img/sharp-libvips-linux-arm64': 1.0.4 - '@img/sharp-libvips-linux-s390x': 1.0.4 - '@img/sharp-libvips-linux-x64': 1.0.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - '@img/sharp-linux-arm': 0.33.5 - '@img/sharp-linux-arm64': 0.33.5 - '@img/sharp-linux-s390x': 0.33.5 - '@img/sharp-linux-x64': 0.33.5 - '@img/sharp-linuxmusl-arm64': 0.33.5 - '@img/sharp-linuxmusl-x64': 0.33.5 - '@img/sharp-wasm32': 0.33.5 - '@img/sharp-win32-ia32': 0.33.5 - '@img/sharp-win32-x64': 0.33.5 + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 shebang-command@2.0.0: dependencies: @@ -7591,18 +7855,8 @@ snapshots: signal-exit@4.1.0: {} - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - - sisteransi@1.0.5: {} - slash@3.0.0: {} - slice-ansi@1.0.0: - dependencies: - is-fullwidth-code-point: 2.0.0 - source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 @@ -7617,19 +7871,7 @@ snapshots: source-map@0.7.4: {} - spdx-correct@3.2.0: - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.16 - - spdx-exceptions@2.3.0: {} - - spdx-expression-parse@3.0.1: - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.16 - - spdx-license-ids@3.0.16: {} + source-map@0.7.6: {} sprintf-js@1.0.3: {} @@ -7641,6 +7883,8 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + streamsearch@1.1.0: {} strict-event-emitter-types@2.0.0: {} @@ -7652,11 +7896,6 @@ snapshots: char-regex: 1.0.2 strip-ansi: 6.0.1 - string-width@2.1.1: - dependencies: - is-fullwidth-code-point: 2.0.0 - strip-ansi: 4.0.0 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -7667,7 +7906,7 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 string_decoder@1.1.1: dependencies: @@ -7677,17 +7916,13 @@ snapshots: dependencies: safe-buffer: 5.2.1 - strip-ansi@4.0.0: - dependencies: - ansi-regex: 3.0.1 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.2.2 strip-bom@3.0.0: {} @@ -7699,14 +7934,9 @@ snapshots: strnum@2.1.1: {} - strtok3@10.2.2: + strtok3@10.3.4: dependencies: '@tokenizer/token': 0.3.0 - peek-readable: 7.0.0 - - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 supports-color@7.2.0: dependencies: @@ -7716,35 +7946,31 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - - swagger-ui-dist@5.21.0: + swagger-ui-dist@5.29.4: dependencies: '@scarf/scarf': 1.4.0 - symbol-observable@1.0.1: {} - symbol-observable@4.0.0: {} - synckit@0.11.6: + synckit@0.11.11: dependencies: - '@pkgr/core': 0.2.4 + '@pkgr/core': 0.2.9 - tapable@2.2.1: {} + tapable@2.3.0: {} - terser-webpack-plugin@5.3.14(webpack@5.99.6): + terser-webpack-plugin@5.3.14(webpack@5.100.2): dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 - schema-utils: 4.3.0 + schema-utils: 4.3.3 serialize-javascript: 6.0.2 - terser: 5.39.0 - webpack: 5.99.6 + terser: 5.44.0 + webpack: 5.100.2 - terser@5.39.0: + terser@5.44.0: dependencies: - '@jridgewell/source-map': 0.3.5 - acorn: 8.14.1 + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -7754,30 +7980,25 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 - through@2.3.8: {} - tiny-inflate@1.0.3: {} - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 + tinyexec@1.0.2: {} tmpl@1.0.5: {} - to-fast-properties@2.0.0: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 toidentifier@1.0.1: {} - token-types@6.0.0: + token-types@6.1.1: dependencies: + '@borewit/text-codec': 0.1.1 '@tokenizer/token': 0.3.0 ieee754: 1.2.1 - tr46@5.0.0: + tr46@5.1.1: dependencies: punycode: 2.3.1 @@ -7787,62 +8008,63 @@ snapshots: dependencies: matchit: 1.1.0 - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.8.3 + typescript: 5.9.3 - ts-jest@29.2.6(@babel/core@7.23.6)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.6))(jest@29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)))(typescript@5.8.3): + ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 - ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.13.10)(ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3)) - jest-util: 29.7.0 + handlebars: 4.7.8 + jest: 30.2.0(@types/node@24.10.0)(ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.7.1 - typescript: 5.8.3 + semver: 7.7.3 + type-fest: 4.41.0 + typescript: 5.9.3 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.23.6 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.23.6) + '@babel/core': 7.28.5 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + babel-jest: 30.2.0(@babel/core@7.28.5) + jest-util: 30.2.0 - ts-loader@9.5.2(typescript@5.8.3)(webpack@5.99.6): + ts-loader@9.5.4(typescript@5.9.3)(webpack@5.100.2): dependencies: chalk: 4.1.2 - enhanced-resolve: 5.18.1 - micromatch: 4.0.5 - semver: 7.7.1 - source-map: 0.7.4 - typescript: 5.8.3 - webpack: 5.99.6 + enhanced-resolve: 5.18.3 + micromatch: 4.0.8 + semver: 7.7.3 + source-map: 0.7.6 + typescript: 5.9.3 + webpack: 5.100.2 - ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3): + ts-node@10.9.2(@types/node@24.10.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.13.10 + '@types/node': 24.10.0 acorn: 8.11.2 acorn-walk: 8.3.1 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.8.3 + typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.18.1 - tapable: 2.2.1 + enhanced-resolve: 5.18.3 + tapable: 2.3.0 tsconfig-paths: 4.2.0 tsconfig-paths@4.2.0: @@ -7863,9 +8085,7 @@ snapshots: type-fest@0.21.3: {} - type-fest@0.6.0: {} - - type-fest@0.8.1: {} + type-fest@4.41.0: {} type-is@1.6.18: dependencies: @@ -7880,25 +8100,33 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.27.0(jiti@2.4.2) - typescript: 5.8.3 + '@typescript-eslint/eslint-plugin': 8.46.3(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) + typescript: 5.9.3 transitivePeerDependencies: - supports-color typescript@5.8.3: {} + typescript@5.9.3: {} + + uglify-js@3.19.3: + optional: true + uid@2.0.2: dependencies: '@lukeed/csprng': 1.1.0 - uint8array-extras@1.4.0: {} + uint8array-extras@1.5.0: {} - undici-types@6.20.0: {} + undici-types@6.21.0: {} + + undici-types@7.16.0: {} unicode-properties@1.4.1: dependencies: @@ -7918,9 +8146,33 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.1.3(browserslist@4.24.4): + unrs-resolver@1.11.1: dependencies: - browserslist: 4.24.4 + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + update-browserslist-db@1.1.4(browserslist@4.27.0): + dependencies: + browserslist: 4.27.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -7934,22 +8186,17 @@ snapshots: utils-merge@1.0.1: {} - uuid@11.0.5: {} + uuid@11.1.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.25 + '@jridgewell/trace-mapping': 0.3.31 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - validate-npm-package-license@3.0.4: - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - - validator@13.11.0: {} + validator@13.15.15: {} vary@1.1.2: {} @@ -7973,7 +8220,7 @@ snapshots: dependencies: makeerror: 1.0.12 - watchpack@2.4.2: + watchpack@2.4.4: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -7986,33 +8233,35 @@ snapshots: webpack-node-externals@3.0.0: {} - webpack-sources@3.2.3: {} + webpack-sources@3.3.3: {} - webpack@5.99.6: + webpack@5.100.2: dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.6 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.14.1 - browserslist: 4.24.4 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.18.1 - es-module-lexer: 1.4.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.27.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.3 + es-module-lexer: 1.7.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 + loader-runner: 4.3.1 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 4.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.99.6) - watchpack: 2.4.2 - webpack-sources: 3.2.3 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.14(webpack@5.100.2) + watchpack: 2.4.4 + webpack-sources: 3.3.3 transitivePeerDependencies: - '@swc/core' - esbuild @@ -8022,15 +8271,21 @@ snapshots: dependencies: iconv-lite: 0.6.3 - whatwg-url@14.1.1: + whatwg-mimetype@3.0.0: {} + + whatwg-url@14.2.0: dependencies: - tr46: 5.0.0 + tr46: 5.1.1 webidl-conversions: 7.0.0 which@2.0.2: dependencies: isexe: 2.0.0 + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -8045,16 +8300,16 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 wrappy@1.0.2: {} - write-file-atomic@4.0.2: + write-file-atomic@5.0.1: dependencies: imurmurhash: 0.1.4 - signal-exit: 3.0.7 + signal-exit: 4.1.0 xtend@4.0.2: {} @@ -8080,4 +8335,4 @@ snapshots: yocto-queue@0.1.0: {} - yoctocolors-cjs@2.1.2: {} + yoctocolors-cjs@2.1.3: {} diff --git a/prisma.config.ts b/prisma.config.ts new file mode 100644 index 00000000..d9f9392c --- /dev/null +++ b/prisma.config.ts @@ -0,0 +1,24 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { defineConfig } from 'prisma/config'; + +const isTestEnv = process.env.NODE_ENV === 'test'; +const envFile = isTestEnv ? '.env.test' : '.env.dev'; +let databaseURL: string | undefined; +try { + readFileSync(join(process.cwd(), envFile), 'utf-8') + .split('\n') + .find((line) => line.includes('DATABASE_URL=')) + ?.replace(/DATABASE_URL="?(\S+?)"?$/, '$1'); +} catch {} + +export default defineConfig({ + schema: join('prisma'), + migrations: { + path: join('prisma', 'migrations'), + }, + engine: 'classic', + datasource: { + url: process.env.DATABASE_URL || (process.env.DATABASE_URL = databaseURL), + }, +}); diff --git a/prisma/models/application.prisma b/prisma/models/application.prisma new file mode 100644 index 00000000..f57bf7ea --- /dev/null +++ b/prisma/models/application.prisma @@ -0,0 +1,51 @@ +model ApiApplication { + id String @id @default(uuid()) + name String + ownerId String + redirectUrl String + clientSecret String + + owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) + apiKeys ApiKey[] +} + +model ApiKey { + id String @id @default(uuid()) + token String @unique + userId String + applicationId String + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + application ApiApplication @relation(fields: [applicationId], references: [id], onDelete: Cascade) + apiKeyPermissions ApiKeyPermission[] + + @@unique([userId, applicationId]) +} + +model ApiKeyPermission { + id String @id @default(uuid()) + permission Permission + apiKeyId String + userId String? // The user targetted by the permission. If null, this is a hard grant. It must thus be null if this is an api permission. + granterId String? // Null if granter was deleted + createdAt DateTime @default(now()) + + apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade) + user User? @relation(name: "target", fields: [userId], references: [id], onDelete: Cascade) + granter User? @relation(name: "granter", fields: [granterId], references: [id], onDelete: SetNull) + + @@unique([apiKeyId, userId, permission]) +} + +enum Permission { + API_SEE_OPINIONS_UE // See the rates of an UE + API_GIVE_OPINIONS_UE // Rate an UE you have done or are doing + API_SEE_ANNALS // See and download annals + API_UPLOAD_ANNALS // Upload an annal + API_MODERATE_ANNALS // Moderate annals + API_MODERATE_COMMENTS // Moderate comments + API_UPLOAD_MEDIA // Upload to media enpoints + + USER_SEE_DETAILS // See personal details about someone, even the ones the user decided to hide + USER_UPDATE_DETAILS // Update personal details about someone +} diff --git a/prisma/models/asso.prisma b/prisma/models/asso.prisma new file mode 100644 index 00000000..29da6941 --- /dev/null +++ b/prisma/models/asso.prisma @@ -0,0 +1,108 @@ +model Asso { + id String @id @default(uuid()) + name String @unique @db.VarChar(100) + mail String @unique @db.VarChar(100) + phoneNumber String? @db.VarChar(30) + website String? @db.VarChar(100) + logoMediaId String? @db.Char(36) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime? + descriptionShortTranslationId String? @unique + descriptionTranslationId String? @unique + assoAccountId String @unique // User account of the asso + + logo ImageMedia? @relation("logo", fields: [logoMediaId], references: [id], onDelete: SetNull) + descriptionImages ImageMedia[] @relation("descriptionImages") + 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[] + assoAccount User @relation(fields: [assoAccountId], references: [id], onDelete: Cascade) +} + +model AssoMembership { + id String @id @default(uuid()) + startAt DateTime + endAt DateTime + createdAt DateTime @default(now()) + userId String + assoId String + roleId String + + user User @relation(fields: [userId], references: [id]) + asso Asso @relation(fields: [assoId], references: [id]) + role AssoMembershipRole @relation(fields: [roleId], references: [id], onDelete: Cascade) + permissions AssoMembershipPermission[] +} + +model AssoMembershipPermission { + id String @id + + assoMembership AssoMembership[] +} + +model AssoMembershipRole { + id String @id @default(uuid()) + name String + position Int + isPresident Boolean + assoId String + + assoMemberships AssoMembership[] + asso Asso @relation(fields: [assoId], references: [id]) +} + +model AssoMessage { + id String @id @default(uuid()) + date DateTime + sendToMobile Boolean + sendAsDaymail Boolean + createdAt DateTime @default(now()) + assoId String + titleTranslationId String @unique + bodyTranslationId String @unique + + asso Asso @relation(fields: [assoId], references: [id]) + titleTranslation Translation @relation(name: "titleTranslation", fields: [titleTranslationId], references: [id], onDelete: Cascade) + bodyTranslation Translation @relation(name: "bodyTranslation", fields: [bodyTranslationId], references: [id], onDelete: Cascade) +} + +model Event { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime + titleTranslationId String @unique + descriptionTranslationId String @unique + + titleTranslation Translation @relation(name: "titleTranslation", fields: [titleTranslationId], references: [id], onDelete: Cascade) + descriptionTranslation Translation @relation(name: "descriptionTranslation", fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + timetableEntries TimetableEntry[] + assos Asso[] + categories EventCategory[] + eventAnswers EventAnswer[] +} + +model EventAnswer { + id String @id @default(uuid()) + answer String @db.VarChar(20) + comment String? @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime + eventId String @default(uuid()) + userId String @default(uuid()) + + event Event @relation(fields: [eventId], references: [id]) + user User @relation(fields: [userId], references: [id]) +} + +model EventCategory { + id String @id @default(uuid()) + name String @unique @db.VarChar(100) + + events Event[] +} \ No newline at end of file diff --git a/prisma/models/timetable.prisma b/prisma/models/timetable.prisma new file mode 100644 index 00000000..c05caa1b --- /dev/null +++ b/prisma/models/timetable.prisma @@ -0,0 +1,49 @@ +model TimetableGroup { + id String @id @default(uuid()) + name String + createdAt DateTime @default(now()) + + userTimetableGroups UserTimetableGroup[] + timetableEntries TimetableEntry[] + timetableEntryOverrides TimetableEntryOverride[] +} + +model TimetableEntry { + id String @id @default(uuid()) + eventStart DateTime @db.DateTime + occurrencesCount Int? @db.UnsignedInt // The number of occurrences, if null, it will be considered infinite + repeatEvery Int? @db.UnsignedInt // In milliseconds + occurrenceDuration Int @db.UnsignedInt // In milliseconds + type TimetableEntryType + location String + eventId String? + createdAt DateTime @default(now()) + + ueCourse UeCourse? + event Event? @relation(fields: [eventId], references: [id]) + overwrittenBy TimetableEntryOverride[] @relation(name: "overrideTimetableEntry") + timetableGroups TimetableGroup[] +} + +model TimetableEntryOverride { + id String @id @default(uuid()) + applyFrom Int // The index of the first occurrence of the event to apply the override to + applyUntil Int // The index of the last occurrence of the event to apply the override to + repeatEvery Int @default(1) @db.UnsignedInt // In number of occurrences of parent entry + occurrenceRelativeStart Int @default(0) @db.UnsignedInt // How many milliseconds after the default beginning of the event should this override start at ? + occurrenceDuration Int? @db.UnsignedInt + delete Boolean @default(false) + location String? + createdAt DateTime @default(now()) + overrideTimetableEntryId String + + overrideTimetableEntry TimetableEntry @relation(name: "overrideTimetableEntry", fields: [overrideTimetableEntryId], references: [id], onDelete: Cascade) + timetableGroups TimetableGroup[] +} + +enum TimetableEntryType { + COURSE + ASSO + DELETE + CUSTOM +} \ No newline at end of file diff --git a/prisma/models/ue.prisma b/prisma/models/ue.prisma new file mode 100644 index 00000000..0f564125 --- /dev/null +++ b/prisma/models/ue.prisma @@ -0,0 +1,298 @@ +model Ue { + 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) + requirements Ue[] @relation(name: "ueRequirements") + ue Ue @relation(fields: [ueId], references: [code]) + annals UeAnnal[] + comments UeComment[] + courses UeCourse[] + credits UeCredit[] + openSemester Semester[] + starVotes UeStarVote[] + usersSubscriptions UserUeSubscription[] + workTime UeWorkTime? +} + +model UeAnnal { + id String @id @default(uuid()) + // The filename is not stored in the database because it is computed from the annal id + uploadComplete Boolean @default(false) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime? + semesterId String + senderId String? + typeId String + ueofCode String + validatedAt DateTime? + + semester Semester @relation(fields: [semesterId], references: [code]) + sender User? @relation(fields: [senderId], references: [id], onDelete: SetNull) + type UeAnnalType @relation(fields: [typeId], references: [id]) + ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) + reports UeAnnalReport[] +} + +model UeAnnalType { + id String @id @default(uuid()) + name String @db.VarChar(255) + + annals UeAnnal[] +} + +model UeAnnalReport { + id String @id @default(uuid()) + annalId String + body String? @db.Text + createdAt DateTime @default(now()) + mitigated Boolean @default(false) + reasonId String + userId String? + + annal UeAnnal @relation(fields: [annalId], references: [id], onDelete: Cascade) + reason UeAnnalReportReason @relation(fields: [reasonId], references: [name]) + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + + @@unique([userId, annalId, reasonId]) // Prevent from spams +} + +model UeAnnalReportReason { + name String @id @db.VarChar(100) + descriptionTranslationId String @unique + + descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + reports UeAnnalReport[] +} + +model UeComment { + id String @id @default(uuid()) + body String @db.Text + isAnonymous Boolean + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) + // Removed @updatedAt because the property is used to display the last datetime the content of the comment was altered on + deletedAt DateTime? + validatedAt DateTime? + authorId String? + lastValidatedBody String? + semesterId String + ueofCode String + + author User? @relation(fields: [authorId], references: [id], onDelete: SetNull) + semester Semester @relation(fields: [semesterId], references: [code]) + ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) + answers UeCommentReply[] + reports UeCommentReport[] + upvotes UeCommentUpvote[] +} + +model UeCommentReply { + id String @id @default(uuid()) + body String @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) + // Removed @updatedAt because the property is used to display the last datetime the content of the reply was altered on + deletedAt DateTime? + commentId String + authorId String? + + author User? @relation(fields: [authorId], references: [id], onDelete: SetNull) + comment UeComment @relation(fields: [commentId], references: [id], onDelete: Cascade) + reports UeCommentReplyReport[] +} + +model UeCommentReport { + id String @id @default(uuid()) + body String @db.Text + createdAt DateTime @default(now()) + mitigated Boolean @default(false) + commentId String + reasonId String + userId String + + comment UeComment @relation(fields: [commentId], 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 +} + +model UeCommentReplyReport { + id String @id @default(uuid()) + body String @db.Text + createdAt DateTime @default(now()) + mitigated Boolean @default(false) + reasonId String + replyId String + userId 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) + + @@unique([userId, replyId, reasonId]) // Prevent from spam +} + +model UeCommentReportReason { + name String @id @db.VarChar(100) + descriptionTranslationId String @unique + + descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + replyReports UeCommentReplyReport[] + reports UeCommentReport[] +} + +model UeCommentUpvote { + id String @id @default(uuid()) + commentId String + createdAt DateTime @default(now()) + userId String? + + 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 + createdAt DateTime @default(now()) + semesterId String + timetableId String @unique() + ueofCode String + + courseExchangesFrom UeCourseExchange[] @relation(name: "courseFrom") + courseExchangesTo UeCourseExchange[] @relation(name: "courseTo") + semester Semester @relation(fields: [semesterId], references: [code]) + ueof Ueof @relation(fields: [ueofCode], references: [code]) + students User[] + timetableEntry TimetableEntry @relation(fields: [timetableId], references: [id]) +} + +model UeCourseExchange { + id String @id @default(uuid()) + 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]) + courseTo UeCourse @relation(name: "courseTo", fields: [courseToId], references: [id]) + responses UeCourseExchangeReply[] +} + +model UeCourseExchangeReply { + id String @id @default(uuid()) + authorId String + body String @db.Text + createdAt DateTime @default(now()) + deletedAt DateTime? + 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()) + categoryId String? + credits Int @db.SmallInt + ueofCode String + + category UeCreditCategory? @relation(fields: [categoryId], references: [code]) + ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) + branchOptions UTTBranchOption[] +} + +model UeCreditCategory { + code String @id @db.Char(2) + name String @db.VarChar(255) + + ueCredits UeCredit[] +} + +model UeofInfo { + id String @id @default(uuid()) + minors String? @db.Text + language String? @db.Text + objectivesTranslationId String? @unique + programTranslationId String? @unique + + objectives Translation? @relation("ueofInfoObjectivesTranslation", fields: [objectivesTranslationId], references: [id], onDelete: Cascade) + program Translation? @relation("ueofInfoProgramTranslation", fields: [programTranslationId], references: [id], onDelete: Cascade) + ueof Ueof? +} + +model UeStarCriterion { + id String @id @default(uuid()) + name String @unique @db.VarChar(255) + descriptionTranslationId String @unique + + descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + starVotes UeStarVote[] +} + +model UeStarVote { + id String @id @default(uuid()) + value Int @db.SmallInt + createdAt DateTime @default(now()) + criterionId String + ueofCode String + userId String? + + criterion UeStarCriterion @relation(fields: [criterionId], references: [id], onDelete: Cascade) + ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + + @@unique([ueofCode, userId, criterionId]) +} + +model UeWorkTime { + id String @id @default(uuid()) + cm Int? + td Int? + tp Int? + the Int? + project Boolean? + internship Int? + ueofCode String @unique + + ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) +} + +enum CourseType { + CM + TD + TP +} diff --git a/prisma/models/user.prisma b/prisma/models/user.prisma new file mode 100644 index 00000000..7b7d0a4d --- /dev/null +++ b/prisma/models/user.prisma @@ -0,0 +1,279 @@ +model User { + id String @id @default(uuid()) + login String @unique @db.VarChar(50) + hash String? + // TODO : maybe a field accountType (that is either CAS or login-password), but this may be implemented in the centralized authentication + studentId Int? + firstName String + lastName String + rgpdId String @unique + preferenceId String @unique + infosId String @unique + mailsPhonesId String @unique + socialNetworkId 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? + bans UserBan[] + bdeContributions UserBDEContribution[] + assoMembership AssoMembership[] + branchSubscriptions UserBranchSubscription[] + formation UserFormation? + addresses UserAddress[] + otherAttributes UserOtherAttributValue[] + uesSubscriptions UserUeSubscription[] + ueStarVotes UeStarVote[] + courses UeCourse[] + eventAnswers EventAnswer[] + annalsSent UeAnnal[] + annalsReported UeAnnalReport[] + comments UeComment[] + commentReplies UeCommentReply[] + commentsReported UeCommentReport[] + repliesReported UeCommentReplyReport[] + gitHubIssues GitHubIssue[] + etuUTTTeam UserEtuUTTTeam[] + courseExchanges UeCourseExchange[] + courseExchangeReplies UeCourseExchangeReply[] + commentUpvotes UeCommentUpvote[] + timetableGroups UserTimetableGroup[] + homepageWidgets UserHomepageWidget[] + privacy UserPrivacy @relation(fields: [privacyId], references: [id]) + apiApplications ApiApplication[] + apiKeys ApiKey[] + apiPermissionsTarget ApiKeyPermission[] @relation(name: "target") + apiPermissionsGrants ApiKeyPermission[] @relation(name: "granter") + asso Asso? + uploadedImages ImageMedia[] +} + +model UserAddress { + id String @id @default(uuid()) + street String? @db.VarChar(255) + postalCode String? @db.VarChar(20) + city String? @db.VarChar(255) + country String? @db.VarChar(50) + userId String + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) +} + +model UserBan { + id String @id @default(uuid()) + readOnlyExpiration DateTime? @db.Date + bannedExpiration DateTime? @db.Date + userId String + + user User @relation(fields: [userId], references: [id]) +} + +model UserBDEContribution { + id String @id @default(uuid()) + start DateTime @db.Date + end DateTime @db.Date + userId String + startSemesterId String + endSemesterId String + + user User @relation(fields: [userId], references: [id]) + startSemester Semester @relation("startSemester", fields: [startSemesterId], references: [code]) + endSemester Semester @relation("endSemester", fields: [endSemesterId], references: [code]) +} + +model UserBranchSubscription { + 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], onDelete: Cascade) + branchOption UTTBranchOption @relation(fields: [branchOptionId], references: [id]) + semester Semester @relation(fields: [semesterCode], references: [code]) +} + +model UserEtuUTTTeam { + id String @id @default(uuid()) + role String @db.Text + userId String + + user User @relation(fields: [userId], references: [id]) + semester Semester[] +} + +model UserFormation { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + userId String @unique + formationId String + followingMethodId String + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + formation UTTFormation @relation(fields: [formationId], references: [name]) + followingMethod UTTFormationFollowingMethod @relation(fields: [followingMethodId], references: [name]) +} + +model UserInfos { + id String @id @default(uuid()) + sex Sex? + nationality String? @db.VarChar(50) + birthday DateTime? @db.Date + avatarMediaId String? @db.Char(36) + nickname String? @db.VarChar(50) + passions String? @db.Text + website String? @db.VarChar(255) + + user User? + avatar ImageMedia? @relation(fields: [avatarMediaId], references: [id], onDelete: SetNull) +} + +model UserMailsPhones { + id String @id @default(uuid()) + mailUTT String? @db.VarChar(255) + mailPersonal String? @db.VarChar(255) + phoneNumber String? @db.VarChar(100) + + user User? +} + +model UserPrivacy { + // For each field, if it is true, it's public. If it is false, it's private. + id String @id @default(uuid()) + mailUTT Boolean @default(false) + mailPersonal Boolean @default(false) + phoneNumber Boolean @default(false) + birthday Boolean @default(false) + birthdayDisplayOnlyAge Boolean @default(false) + sex Boolean @default(false) + nationality Boolean @default(false) + discord Boolean @default(false) + address AddressPrivacy @default(ALL_PRIVATE) + timetable Boolean @default(false) + + user User? +} + +model UserOtherAttribut { + name String @id @db.VarChar(100) + type AttributeType + + values UserOtherAttributValue[] +} + +model UserOtherAttributValue { + id String @id @default(uuid()) + value String @db.Text + userId String + attributId String + + user User @relation(fields: [userId], references: [id]) + attribut UserOtherAttribut @relation(fields: [attributId], references: [name]) +} + +model UserHomepageWidget { + id String @id @default(uuid()) + widget String @db.VarChar(20) + x Int + y Int + width Int + height Int + userId String + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) +} + +model UserPreference { + id String @id @default(uuid()) + language Language @default(fr) + wantDaymail Boolean @default(false) + wantDayNotif Boolean @default(false) + wantDiscordUtt Boolean @default(false) + + user User? +} + +model UserRGPD { + id String @id @default(uuid()) + isKeepingAccount Boolean? + isDeletingEverything Boolean? + + user User? +} + +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) + + user User? +} + +model UserTimestamps { + id String @id @default(uuid()) + lastLoginDate DateTime? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + userId String @unique + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) +} + +model UserTimetableGroup { + id String @id @default(uuid()) + timetableGroupId String + userId String + priority Int + + user User @relation(fields: [userId], references: [id]) + timetableGroup TimetableGroup @relation(fields: [timetableGroupId], references: [id]) + + @@unique([timetableGroupId, userId]) +} + +model UserUeSubscription { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + userId String + ueofCode String + semesterId String + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + ueof Ueof @relation(fields: [ueofCode], references: [code]) + semester Semester @relation(fields: [semesterId], references: [code]) + + @@unique([userId, ueofCode, semesterId]) +} + +enum UserType { + STUDENT + FORMER_STUDENT + TEACHER + EMPLOYEE + ASSOCIATION + OTHER +} + +enum AddressPrivacy { + ALL_PRIVATE + CITY_PRIVATE + ADDRESS_PRIVATE + ALL_PUBLIC +} + +enum Sex { + MALE + FEMALE + OTHER +} diff --git a/prisma/models/utt.prisma b/prisma/models/utt.prisma new file mode 100644 index 00000000..fcd1ae5e --- /dev/null +++ b/prisma/models/utt.prisma @@ -0,0 +1,60 @@ +model Semester { + code String @id @db.Char(3) + start DateTime @db.Date + end DateTime @db.Date + + openedUes Ueof[] + annals UeAnnal[] + comments UeComment[] + courses UeCourse[] + bdeContributionsStart UserBDEContribution[] @relation("startSemester") + bdeContributionsEnd UserBDEContribution[] @relation("endSemester") + branchSubscriptions UserBranchSubscription[] + ueSubscriptions UserUeSubscription[] + etuUTTTeams UserEtuUTTTeam[] +} + +model UTTBranch { + 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 + + descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + branchOptions UTTBranchOption[] +} + +model UTTBranchOption { + id String @id @default(uuid()) + code String @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) + uecredits UeCredit[] + branchSubscriptions UserBranchSubscription[] + + @@unique([code, branchCode]) +} + +model UTTFormation { + name String @id @db.VarChar(100) + descriptionTranslationId String @unique + + descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + userFormations UserFormation[] +} + +model UTTFormationFollowingMethod { + name String @id @db.VarChar(100) + descriptionTranslationId String @unique + + descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) + userFormations UserFormation[] +} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ee6bef46..5a059bc4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,5 +1,7 @@ generator client { - provider = "prisma-client-js" + provider = "prisma-client" + output = "../src/prisma/types" + engineType = "client" } datasource db { @@ -7,152 +9,6 @@ datasource db { url = env("DATABASE_URL") } -model ApiApplication { - id String @id @default(uuid()) - name String - ownerId String - redirectUrl String - clientSecret String - - owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) - apiKeys ApiKey[] -} - -model ApiKey { - id String @id @default(uuid()) - token String @unique - userId String - applicationId String - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - application ApiApplication @relation(fields: [applicationId], references: [id], onDelete: Cascade) - apiKeyPermissions ApiKeyPermission[] - - @@unique([userId, applicationId]) -} - -model ApiKeyPermission { - id String @id @default(uuid()) - permission Permission - apiKeyId String - userId String? // The user targetted by the permission. If null, this is a hard grant. It must thus be null if this is an api permission. - granterId String? // Null if granter was deleted - createdAt DateTime @default(now()) - - apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade) - user User? @relation(name: "target", fields: [userId], references: [id], onDelete: Cascade) - granter User? @relation(name: "granter", fields: [granterId], references: [id], onDelete: SetNull) - - @@unique([apiKeyId, userId, permission]) -} - -model Asso { - id String @id @default(uuid()) - name String @unique @db.VarChar(100) - mail String @unique @db.VarChar(100) - phoneNumber String? @db.VarChar(30) - website String? @db.VarChar(100) - logo String? @db.VarChar(100) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime? - descriptionShortTranslationId String? @unique - descriptionTranslationId String? @unique - assoAccountId String @unique // User account of the asso - - 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[] - assoAccount User @relation(fields: [assoAccountId], references: [id], onDelete: Cascade) -} - -model AssoMembership { - id String @id @default(uuid()) - startAt DateTime - endAt DateTime - createdAt DateTime @default(now()) - userId String - assoId String - roleId String - - user User @relation(fields: [userId], references: [id]) - asso Asso @relation(fields: [assoId], references: [id]) - role AssoMembershipRole @relation(fields: [roleId], references: [id], onDelete: Cascade) - permissions AssoMembershipPermission[] -} - -model AssoMembershipPermission { - id String @id - - assoMembership AssoMembership[] -} - -model AssoMembershipRole { - id String @id @default(uuid()) - name String - position Int - isPresident Boolean - assoId String - - assoMemberships AssoMembership[] - asso Asso @relation(fields: [assoId], references: [id]) -} - -model AssoMessage { - id String @id @default(uuid()) - date DateTime - sendToMobile Boolean - sendAsDaymail Boolean - createdAt DateTime @default(now()) - assoId String - titleTranslationId String @unique - bodyTranslationId String @unique - - asso Asso @relation(fields: [assoId], references: [id]) - titleTranslation Translation @relation(name: "titleTranslation", fields: [titleTranslationId], references: [id], onDelete: Cascade) - bodyTranslation Translation @relation(name: "bodyTranslation", fields: [bodyTranslationId], references: [id], onDelete: Cascade) -} - -model Event { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime - titleTranslationId String @unique - descriptionTranslationId String @unique - - titleTranslation Translation @relation(name: "titleTranslation", fields: [titleTranslationId], references: [id], onDelete: Cascade) - descriptionTranslation Translation @relation(name: "descriptionTranslation", fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - timetableEntries TimetableEntry[] - assos Asso[] - categories EventCategory[] - eventAnswers EventAnswer[] -} - -model EventAnswer { - id String @id @default(uuid()) - answer String @db.VarChar(20) - comment String? @db.Text - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime - eventId String @default(uuid()) - userId String @default(uuid()) - - event Event @relation(fields: [eventId], references: [id]) - user User @relation(fields: [userId], references: [id]) -} - -model EventCategory { - id String @id @default(uuid()) - name String @unique @db.VarChar(100) - - events Event[] -} - model GitHubIssue { id String @id @default(uuid()) gitHubIssueId Int @@ -162,63 +18,20 @@ model GitHubIssue { user User @relation(fields: [userId], references: [id]) } -model Semester { - code String @id @db.Char(3) - start DateTime @db.Date - end DateTime @db.Date - - openedUes Ueof[] - annals UeAnnal[] - comments UeComment[] - courses UeCourse[] - bdeContributionsStart UserBDEContribution[] @relation("startSemester") - bdeContributionsEnd UserBDEContribution[] @relation("endSemester") - branchSubscriptions UserBranchSubscription[] - ueSubscriptions UserUeSubscription[] - etuUTTTeams UserEtuUTTTeam[] -} - -model TimetableGroup { - id String @id @default(uuid()) - name String - createdAt DateTime @default(now()) +model ImageMedia { + id String @id @default(uuid()) @db.Char(36) + size Int @db.UnsignedInt + width Int @db.UnsignedInt + height Int @db.UnsignedInt + uploadedAt DateTime @default(now()) + isPublic Boolean @default(false) + uploaderId String? + preset ImageMediaPreset - userTimetableGroups UserTimetableGroup[] - timetableEntries TimetableEntry[] - timetableEntryOverrides TimetableEntryOverride[] -} - -model TimetableEntry { - id String @id @default(uuid()) - eventStart DateTime @db.DateTime - occurrencesCount Int? @db.UnsignedInt // The number of occurrences, if null, it will be considered infinite - repeatEvery Int? @db.UnsignedInt // In milliseconds - occurrenceDuration Int @db.UnsignedInt // In milliseconds - type TimetableEntryType - location String - eventId String? - createdAt DateTime @default(now()) - - ueCourse UeCourse? - event Event? @relation(fields: [eventId], references: [id]) - overwrittenBy TimetableEntryOverride[] @relation(name: "overrideTimetableEntry") - timetableGroups TimetableGroup[] -} - -model TimetableEntryOverride { - id String @id @default(uuid()) - applyFrom Int // The index of the first occurrence of the event to apply the override to - applyUntil Int // The index of the last occurrence of the event to apply the override to - repeatEvery Int @default(1) @db.UnsignedInt // In number of occurrences of parent entry - occurrenceRelativeStart Int @default(0) @db.UnsignedInt // How many milliseconds after the default beginning of the event should this override start at ? - occurrenceDuration Int? @db.UnsignedInt - delete Boolean @default(false) - location String? - createdAt DateTime @default(now()) - overrideTimetableEntryId String - - overrideTimetableEntry TimetableEntry @relation(name: "overrideTimetableEntry", fields: [overrideTimetableEntryId], references: [id], onDelete: Cascade) - timetableGroups TimetableGroup[] + uploader User? @relation(fields: [uploaderId], references: [id]) + avatarForUsers UserInfos[] + logoForAssos Asso[] @relation("logo") + descriptionForAssos Asso[] @relation("descriptionImages") } model Translation { @@ -247,609 +60,6 @@ model Translation { ueNames Ueof? } -model Ue { - 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) - requirements Ue[] @relation(name: "ueRequirements") - ue Ue @relation(fields: [ueId], references: [code]) - annals UeAnnal[] - comments UeComment[] - courses UeCourse[] - credits UeCredit[] - openSemester Semester[] - starVotes UeStarVote[] - usersSubscriptions UserUeSubscription[] - workTime UeWorkTime? -} - -model UeAnnal { - id String @id @default(uuid()) - // The filename is not stored in the database because it is computed from the annal id - uploadComplete Boolean @default(false) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime? - semesterId String - senderId String? - typeId String - ueofCode String - validatedAt DateTime? - - semester Semester @relation(fields: [semesterId], references: [code]) - sender User? @relation(fields: [senderId], references: [id], onDelete: SetNull) - type UeAnnalType @relation(fields: [typeId], references: [id]) - ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) - reports UeAnnalReport[] -} - -model UeAnnalType { - id String @id @default(uuid()) - name String @db.VarChar(255) - - annals UeAnnal[] -} - -model UeAnnalReport { - id String @id @default(uuid()) - annalId String - body String? @db.Text - createdAt DateTime @default(now()) - mitigated Boolean @default(false) - reasonId String - userId String? - - annal UeAnnal @relation(fields: [annalId], references: [id], onDelete: Cascade) - reason UeAnnalReportReason @relation(fields: [reasonId], references: [name]) - user User? @relation(fields: [userId], references: [id], onDelete: SetNull) - - @@unique([userId, annalId, reasonId]) // Prevent from spams -} - -model UeAnnalReportReason { - name String @id @db.VarChar(100) - descriptionTranslationId String @unique - - descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - reports UeAnnalReport[] -} - -model UeComment { - id String @id @default(uuid()) - body String @db.Text - isAnonymous Boolean - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) - // Removed @updatedAt because the property is used to display the last datetime the content of the comment was altered on - deletedAt DateTime? - validatedAt DateTime? - authorId String? - lastValidatedBody String? - semesterId String - ueofCode String - - author User? @relation(fields: [authorId], references: [id], onDelete: SetNull) - semester Semester @relation(fields: [semesterId], references: [code]) - ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) - answers UeCommentReply[] - reports UeCommentReport[] - upvotes UeCommentUpvote[] -} - -model UeCommentReply { - id String @id @default(uuid()) - body String @db.Text - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) - // Removed @updatedAt because the property is used to display the last datetime the content of the reply was altered on - deletedAt DateTime? - commentId String - authorId String? - - author User? @relation(fields: [authorId], references: [id], onDelete: SetNull) - comment UeComment @relation(fields: [commentId], references: [id], onDelete: Cascade) - reports UeCommentReplyReport[] -} - -model UeCommentReport { - id String @id @default(uuid()) - body String @db.Text - createdAt DateTime @default(now()) - mitigated Boolean @default(false) - commentId String - reasonId String - userId String - - comment UeComment @relation(fields: [commentId], 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 -} - -model UeCommentReplyReport { - id String @id @default(uuid()) - body String @db.Text - createdAt DateTime @default(now()) - mitigated Boolean @default(false) - reasonId String - replyId String - userId 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) - - @@unique([userId, replyId, reasonId]) // Prevent from spam -} - -model UeCommentReportReason { - name String @id @db.VarChar(100) - descriptionTranslationId String @unique - - descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - replyReports UeCommentReplyReport[] - reports UeCommentReport[] -} - -model UeCommentUpvote { - id String @id @default(uuid()) - commentId String - createdAt DateTime @default(now()) - userId String? - - 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 - createdAt DateTime @default(now()) - semesterId String - timetableId String @unique() - ueofCode String - - courseExchangesFrom UeCourseExchange[] @relation(name: "courseFrom") - courseExchangesTo UeCourseExchange[] @relation(name: "courseTo") - semester Semester @relation(fields: [semesterId], references: [code]) - ueof Ueof @relation(fields: [ueofCode], references: [code]) - students User[] - timetableEntry TimetableEntry @relation(fields: [timetableId], references: [id]) -} - -model UeCourseExchange { - id String @id @default(uuid()) - 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]) - courseTo UeCourse @relation(name: "courseTo", fields: [courseToId], references: [id]) - responses UeCourseExchangeReply[] -} - -model UeCourseExchangeReply { - id String @id @default(uuid()) - authorId String - body String @db.Text - createdAt DateTime @default(now()) - deletedAt DateTime? - 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()) - categoryId String? - credits Int @db.SmallInt - ueofCode String - - category UeCreditCategory? @relation(fields: [categoryId], references: [code]) - ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) - branchOptions UTTBranchOption[] -} - -model UeCreditCategory { - code String @id @db.Char(2) - name String @db.VarChar(255) - - ueCredits UeCredit[] -} - -model UeofInfo { - id String @id @default(uuid()) - minors String? @db.Text - language String? @db.Text - objectivesTranslationId String? @unique - programTranslationId String? @unique - - objectives Translation? @relation("ueofInfoObjectivesTranslation", fields: [objectivesTranslationId], references: [id], onDelete: Cascade) - program Translation? @relation("ueofInfoProgramTranslation", fields: [programTranslationId], references: [id], onDelete: Cascade) - ueof Ueof? -} - -model UeStarCriterion { - id String @id @default(uuid()) - name String @unique @db.VarChar(255) - descriptionTranslationId String @unique - - descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - starVotes UeStarVote[] -} - -model UeStarVote { - id String @id @default(uuid()) - value Int @db.SmallInt - createdAt DateTime @default(now()) - criterionId String - ueofCode String - userId String? - - criterion UeStarCriterion @relation(fields: [criterionId], references: [id], onDelete: Cascade) - ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) - user User? @relation(fields: [userId], references: [id], onDelete: SetNull) - - @@unique([ueofCode, userId, criterionId]) -} - -model UeWorkTime { - id String @id @default(uuid()) - cm Int? - td Int? - tp Int? - the Int? - project Boolean? - internship Int? - ueofCode String @unique - - ueof Ueof @relation(fields: [ueofCode], references: [code], onDelete: Cascade) -} - -model User { - id String @id @default(uuid()) - login String @unique @db.VarChar(50) - hash String? - // TODO : maybe a field accountType (that is either CAS or login-password), but this may be implemented in the centralized authentication - studentId Int? - firstName String - lastName String - rgpdId String @unique - preferenceId String @unique - infosId String @unique - mailsPhonesId String @unique - socialNetworkId 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? - bans UserBan[] - bdeContributions UserBDEContribution[] - assoMembership AssoMembership[] - branchSubscriptions UserBranchSubscription[] - formation UserFormation? - addresses UserAddress[] - otherAttributes UserOtherAttributValue[] - uesSubscriptions UserUeSubscription[] - ueStarVotes UeStarVote[] - courses UeCourse[] - eventAnswers EventAnswer[] - annalsSent UeAnnal[] - annalsReported UeAnnalReport[] - comments UeComment[] - commentReplies UeCommentReply[] - commentsReported UeCommentReport[] - repliesReported UeCommentReplyReport[] - gitHubIssues GitHubIssue[] - etuUTTTeam UserEtuUTTTeam[] - courseExchanges UeCourseExchange[] - courseExchangeReplies UeCourseExchangeReply[] - commentUpvotes UeCommentUpvote[] - timetableGroups UserTimetableGroup[] - homepageWidgets UserHomepageWidget[] - privacy UserPrivacy @relation(fields: [privacyId], references: [id]) - apiApplications ApiApplication[] - apiKeys ApiKey[] - apiPermissionsTarget ApiKeyPermission[] @relation(name: "target") - apiPermissionsGrants ApiKeyPermission[] @relation(name: "granter") - asso Asso? -} - -model UserAddress { - id String @id @default(uuid()) - street String? @db.VarChar(255) - postalCode String? @db.VarChar(20) - city String? @db.VarChar(255) - country String? @db.VarChar(50) - userId String - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) -} - -model UserBan { - id String @id @default(uuid()) - readOnlyExpiration DateTime? @db.Date - bannedExpiration DateTime? @db.Date - userId String - - user User @relation(fields: [userId], references: [id]) -} - -model UserBDEContribution { - id String @id @default(uuid()) - start DateTime @db.Date - end DateTime @db.Date - userId String - startSemesterId String - endSemesterId String - - user User @relation(fields: [userId], references: [id]) - startSemester Semester @relation("startSemester", fields: [startSemesterId], references: [code]) - endSemester Semester @relation("endSemester", fields: [endSemesterId], references: [code]) -} - -model UserBranchSubscription { - 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], onDelete: Cascade) - branchOption UTTBranchOption @relation(fields: [branchOptionId], references: [id]) - semester Semester @relation(fields: [semesterCode], references: [code]) -} - -model UserEtuUTTTeam { - id String @id @default(uuid()) - role String @db.Text - userId String - - user User @relation(fields: [userId], references: [id]) - semester Semester[] -} - -model UserFormation { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - userId String @unique - formationId String - followingMethodId String - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - formation UTTFormation @relation(fields: [formationId], references: [name]) - followingMethod UTTFormationFollowingMethod @relation(fields: [followingMethodId], references: [name]) -} - -model UserInfos { - id String @id @default(uuid()) - sex Sex? - nationality String? @db.VarChar(50) - birthday DateTime? @db.Date - avatar String @default("default.png") @db.VarChar(255) - nickname String? @db.VarChar(50) - passions String? @db.Text - website String? @db.VarChar(255) - - user User? -} - -model UserMailsPhones { - id String @id @default(uuid()) - mailUTT String? @db.VarChar(255) - mailPersonal String? @db.VarChar(255) - phoneNumber String? @db.VarChar(100) - - user User? -} - -model UserPrivacy { - // For each field, if it is true, it's public. If it is false, it's private. - id String @id @default(uuid()) - mailUTT Boolean @default(false) - mailPersonal Boolean @default(false) - phoneNumber Boolean @default(false) - birthday Boolean @default(false) - birthdayDisplayOnlyAge Boolean @default(false) - sex Boolean @default(false) - nationality Boolean @default(false) - discord Boolean @default(false) - address AddressPrivacy @default(ALL_PRIVATE) - timetable Boolean @default(false) - - user User? -} - -model UserOtherAttribut { - name String @id @db.VarChar(100) - type AttributeType - - values UserOtherAttributValue[] -} - -model UserOtherAttributValue { - id String @id @default(uuid()) - value String @db.Text - userId String - attributId String - - user User @relation(fields: [userId], references: [id]) - attribut UserOtherAttribut @relation(fields: [attributId], references: [name]) -} - -model UserHomepageWidget { - id String @id @default(uuid()) - widget String @db.VarChar(20) - x Int - y Int - width Int - height Int - userId String - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) -} - -model UserPreference { - id String @id @default(uuid()) - language Language @default(fr) - wantDaymail Boolean @default(false) - wantDayNotif Boolean @default(false) - wantDiscordUtt Boolean @default(false) - - user User? -} - -model UserRGPD { - id String @id @default(uuid()) - isKeepingAccount Boolean? - isDeletingEverything Boolean? - - user User? -} - -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) - - user User? -} - -model UserTimestamps { - id String @id @default(uuid()) - lastLoginDate DateTime? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - userId String @unique - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) -} - -model UserTimetableGroup { - id String @id @default(uuid()) - timetableGroupId String - userId String - priority Int - - user User @relation(fields: [userId], references: [id]) - timetableGroup TimetableGroup @relation(fields: [timetableGroupId], references: [id]) - - @@unique([timetableGroupId, userId]) -} - -model UserUeSubscription { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - userId String - ueofCode String - semesterId String - - user User @relation(fields: [userId], references: [id]) - ueof Ueof @relation(fields: [ueofCode], references: [code]) - semester Semester @relation(fields: [semesterId], references: [code]) - - @@unique([userId, ueofCode, semesterId]) -} - -model UTTBranch { - 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 - - descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - branchOptions UTTBranchOption[] -} - -model UTTBranchOption { - id String @id @default(uuid()) - code String @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) - uecredits UeCredit[] - branchSubscriptions UserBranchSubscription[] - - @@unique([code, branchCode]) -} - -model UTTFormation { - name String @id @db.VarChar(100) - descriptionTranslationId String @unique - - descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - userFormations UserFormation[] -} - -model UTTFormationFollowingMethod { - name String @id @db.VarChar(100) - descriptionTranslationId String @unique - - descriptionTranslation Translation @relation(fields: [descriptionTranslationId], references: [id], onDelete: Cascade) - userFormations UserFormation[] -} - -enum UserType { - STUDENT - FORMER_STUDENT - TEACHER - EMPLOYEE - ASSOCIATION - OTHER -} - enum AttributeType { BOOL INT @@ -860,12 +70,6 @@ enum AttributeType { DATETIME } -enum CourseType { - CM - TD - TP -} - enum Language { fr en @@ -874,39 +78,7 @@ enum Language { zh } -enum Sex { - MALE - FEMALE - OTHER -} - -enum Week { - A - B -} - -enum TimetableEntryType { - COURSE - ASSO - DELETE +enum ImageMediaPreset { + AVATAR CUSTOM } - -enum AddressPrivacy { - ALL_PRIVATE - CITY_PRIVATE - ADDRESS_PRIVATE - ALL_PUBLIC -} - -enum Permission { - API_SEE_OPINIONS_UE // See the rates of an UE - API_GIVE_OPINIONS_UE // Rate an UE you have done or are doing - API_SEE_ANNALS // See and download annals - API_UPLOAD_ANNALS // Upload an annal - API_MODERATE_ANNALS // Moderate annals - API_MODERATE_COMMENTS // Moderate comments - - USER_SEE_DETAILS // See personal details about someone, even the ones the user decided to hide - USER_UPDATE_DETAILS // Update personal details about someone -} diff --git a/prisma/seed/modules/asso.seed.ts b/prisma/seed/modules/asso.seed.ts index b806bcd0..65700a82 100644 --- a/prisma/seed/modules/asso.seed.ts +++ b/prisma/seed/modules/asso.seed.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { PrismaClient, UserType } from '@prisma/client'; +import { PrismaClient, UserType } from '../../../src/prisma/types'; export default function assoSeed(prisma: PrismaClient) { console.log('Seeding assos...'); @@ -15,7 +15,29 @@ export default function assoSeed(prisma: PrismaClient) { mail: faker.internet.email(), phoneNumber: faker.phone.number(), website: faker.internet.domainName(), - logo: faker.image.urlLoremFlickr({ category: 'business' }), + logo: { + create: { + height: 100, + width: 100, + size: 1024, + isPublic: true, + preset: 'AVATAR', + uploader: { + create: { + login: name, + firstName: '', + lastName: '', + userType: UserType.ASSOCIATION, + socialNetwork: { create: {} }, + mailsPhones: { create: {} }, + rgpd: { create: {} }, + preference: { create: {} }, + infos: { create: {} }, + privacy: { create: {} }, + }, + }, + }, + }, createdAt: date, updatedAt: date, descriptionShortTranslation: { @@ -42,8 +64,8 @@ export default function assoSeed(prisma: PrismaClient) { preference: { create: {} }, infos: { create: {} }, privacy: { create: {} }, - } - } + }, + }, }, }), ); diff --git a/prisma/seed/modules/assoMembership.seed.ts b/prisma/seed/modules/assoMembership.seed.ts index f67954e4..cf675063 100644 --- a/prisma/seed/modules/assoMembership.seed.ts +++ b/prisma/seed/modules/assoMembership.seed.ts @@ -1,6 +1,5 @@ import { faker } from '@faker-js/faker'; -import { PrismaClient } from '@prisma/client'; -import { RawAssoMembershipRole, RawUser } from 'src/prisma/types'; +import { PrismaClient, RawAssoMembershipRole, RawUser } from '../../../src/prisma/types'; import { Asso } from '../../../src/assos/interfaces/asso.interface'; export default function assoMembershipSeed( diff --git a/prisma/seed/modules/assoMembershipRole.seed.ts b/prisma/seed/modules/assoMembershipRole.seed.ts index 3baef26b..60a56873 100644 --- a/prisma/seed/modules/assoMembershipRole.seed.ts +++ b/prisma/seed/modules/assoMembershipRole.seed.ts @@ -1,7 +1,6 @@ import { faker } from '@faker-js/faker'; -import { PrismaClient } from '@prisma/client'; import { Asso } from '../../../src/assos/interfaces/asso.interface'; -import { RawAssoMembershipRole } from '../../../src/prisma/types'; +import { PrismaClient, RawAssoMembershipRole } from '../../../src/prisma/types'; export default function assoMembershipRoleSeed(prisma: PrismaClient, assos: Asso[]): Promise { console.log('Seeding assoMembershipRoles'); diff --git a/prisma/seed/modules/branch.seed.ts b/prisma/seed/modules/branch.seed.ts index 6c54b55d..98ea4b99 100644 --- a/prisma/seed/modules/branch.seed.ts +++ b/prisma/seed/modules/branch.seed.ts @@ -1,6 +1,5 @@ -import { PrismaClient } from '@prisma/client'; import { faker } from '@faker-js/faker'; -import { RawBranch } from '../../../src/prisma/types'; +import { PrismaClient, RawBranch } from '../../../src/prisma/types'; const FAKER_ROUNDS = 8; diff --git a/prisma/seed/modules/branchOption.seed.ts b/prisma/seed/modules/branchOption.seed.ts index 3802ca12..73a109dd 100644 --- a/prisma/seed/modules/branchOption.seed.ts +++ b/prisma/seed/modules/branchOption.seed.ts @@ -1,6 +1,5 @@ import { faker } from '@faker-js/faker'; -import { RawBranch, RawBranchOption } from '../../../src/prisma/types'; -import { PrismaClient, PrismaPromise } from '@prisma/client'; +import { PrismaClient, RawBranch, RawBranchOption } from '../../../src/prisma/types'; const MAX_FAKER_ROUNDS = 4; @@ -9,7 +8,7 @@ export default async function branchOptionSeed( branches: RawBranch[], ): Promise { console.log('Seeding branch options...'); - const branchOptions: PrismaPromise[] = []; + const branchOptions: Promise[] = []; for (const branch of branches) { branchOptions.push( prisma.uTTBranchOption.create({ diff --git a/prisma/seed/modules/creditCategory.seed.ts b/prisma/seed/modules/creditCategory.seed.ts index f420887c..8fa09ac0 100644 --- a/prisma/seed/modules/creditCategory.seed.ts +++ b/prisma/seed/modules/creditCategory.seed.ts @@ -1,5 +1,4 @@ -import { RawCreditCategory } from '../../../src/prisma/types'; -import { PrismaClient } from '@prisma/client'; +import { PrismaClient, RawCreditCategory } from '../../../src/prisma/types'; import { faker } from '@faker-js/faker'; const FAKER_ROUNDS = 5; diff --git a/prisma/seed/modules/semester.seed.ts b/prisma/seed/modules/semester.seed.ts index c5e248fd..b06d1a0a 100644 --- a/prisma/seed/modules/semester.seed.ts +++ b/prisma/seed/modules/semester.seed.ts @@ -1,5 +1,4 @@ -import { PrismaClient } from '@prisma/client'; -import { RawSemester } from '../../../src/prisma/types'; +import { PrismaClient, RawSemester } from '../../../src/prisma/types'; export default function semesterSeed(prisma: PrismaClient): Promise { console.log('Seeding semesters...'); diff --git a/prisma/seed/modules/ue.seed.ts b/prisma/seed/modules/ue.seed.ts index 687bfafb..371f238a 100644 --- a/prisma/seed/modules/ue.seed.ts +++ b/prisma/seed/modules/ue.seed.ts @@ -1,6 +1,5 @@ -import { PrismaClient } from '@prisma/client'; import { faker } from '@faker-js/faker'; -import { RawBranchOption, RawCreditCategory, RawSemester, RawUe } from '../../../src/prisma/types'; +import { PrismaClient, RawBranchOption, RawCreditCategory, RawSemester, RawUe } from '../../../src/prisma/types'; import { generateTranslation } from '../utils'; const FAKER_ROUNDS = 20; diff --git a/prisma/seed/modules/ueComment.seed.ts b/prisma/seed/modules/ueComment.seed.ts index 78bfcda7..0457cfec 100644 --- a/prisma/seed/modules/ueComment.seed.ts +++ b/prisma/seed/modules/ueComment.seed.ts @@ -1,5 +1,11 @@ -import { RawSemester, RawUeComment, RawUser, RawUserUeSubscription } from '../../../src/prisma/types'; -import { Prisma, PrismaClient } from '@prisma/client'; +import { + Prisma, + PrismaClient, + RawSemester, + RawUeComment, + RawUser, + RawUserUeSubscription, +} from '../../../src/prisma/types'; import { faker } from '@faker-js/faker'; const FAKER_ROUNDS = 100; diff --git a/prisma/seed/modules/ueStarCriterion.seed.ts b/prisma/seed/modules/ueStarCriterion.seed.ts index 9f1dcaf6..e8e94110 100644 --- a/prisma/seed/modules/ueStarCriterion.seed.ts +++ b/prisma/seed/modules/ueStarCriterion.seed.ts @@ -1,5 +1,4 @@ -import { RawUeStarCriterion } from '../../../src/prisma/types'; -import { PrismaClient } from '@prisma/client'; +import { PrismaClient, RawUeStarCriterion } from '../../../src/prisma/types'; import { faker } from '@faker-js/faker'; const FAKER_ROUNDS = 5; diff --git a/prisma/seed/modules/ueStarVotes.seed.ts b/prisma/seed/modules/ueStarVotes.seed.ts index bbafbfc0..21781c86 100644 --- a/prisma/seed/modules/ueStarVotes.seed.ts +++ b/prisma/seed/modules/ueStarVotes.seed.ts @@ -1,5 +1,4 @@ -import { RawUeStarVote, RawUeStarCriterion, RawUserUeSubscription } from '../../../src/prisma/types'; -import { PrismaClient } from '@prisma/client'; +import { PrismaClient, RawUeStarVote, RawUeStarCriterion, RawUserUeSubscription } from '../../../src/prisma/types'; import { faker } from '@faker-js/faker'; export default function ueStarVotesSeed( diff --git a/prisma/seed/modules/ueSubscription.seed.ts b/prisma/seed/modules/ueSubscription.seed.ts index 4772614a..8642de20 100644 --- a/prisma/seed/modules/ueSubscription.seed.ts +++ b/prisma/seed/modules/ueSubscription.seed.ts @@ -1,5 +1,4 @@ -import { RawSemester, RawUe, RawUser, RawUserUeSubscription } from '../../../src/prisma/types'; -import { PrismaClient } from '@prisma/client'; +import { PrismaClient, RawSemester, RawUe, RawUser, RawUserUeSubscription } from '../../../src/prisma/types'; import { faker } from '@faker-js/faker'; import { OF_SUFFIX } from './ue.seed'; diff --git a/prisma/seed/modules/user.seed.ts b/prisma/seed/modules/user.seed.ts index 5c5539bd..70c797aa 100644 --- a/prisma/seed/modules/user.seed.ts +++ b/prisma/seed/modules/user.seed.ts @@ -1,5 +1,4 @@ -import { PrismaClient, Sex } from '@prisma/client'; -import { RawUser } from '../../../src/prisma/types'; +import { PrismaClient, Sex, RawUser } from '../../../src/prisma/types'; import { faker } from '@faker-js/faker'; import * as bcrypt from 'bcryptjs'; import { DEFAULT_APPLICATION } from '../utils'; diff --git a/prisma/seed/seed.ts b/prisma/seed/seed.ts index 4a269b79..107d4088 100644 --- a/prisma/seed/seed.ts +++ b/prisma/seed/seed.ts @@ -1,4 +1,5 @@ -import { PrismaClient } from '@prisma/client'; +import { PrismaMariaDb } from '@prisma/adapter-mariadb'; +import { PrismaClient } from '../../src/prisma/types'; import ueSeed from './modules/ue.seed'; import { userSeed } from './modules/user.seed'; import { faker } from '@faker-js/faker'; @@ -16,7 +17,7 @@ import assoMembershipRoleSeed from './modules/assoMembershipRole.seed'; import assoMembershipSeed from './modules/assoMembership.seed'; import { generateDefaultApplication } from './utils'; -const prisma = new PrismaClient(); +const prisma = new PrismaClient({ adapter: new PrismaMariaDb(process.env.DATABASE_URL) }); async function main() { console.log('Flushing database...'); await cleanDb(prisma); diff --git a/prisma/seed/utils.ts b/prisma/seed/utils.ts index 2093fbd7..edd89b77 100644 --- a/prisma/seed/utils.ts +++ b/prisma/seed/utils.ts @@ -1,7 +1,7 @@ import { Faker, faker } from '@faker-js/faker'; import { Entity, FakeEntityMap } from '../../test/utils/fakedb'; import { Translation } from 'src/prisma/types'; -import { PrismaClient, UserType } from '@prisma/client'; +import { PrismaClient, UserType } from '../../src/prisma/types'; import { PrismaService } from '../../src/prisma/prisma.service'; // While waiting to be able to recover the real data diff --git a/scripts/seed/aliases.ts b/scripts/seed/aliases.ts index fcd6c2ab..117fe01b 100644 --- a/scripts/seed/aliases.ts +++ b/scripts/seed/aliases.ts @@ -1,6 +1,7 @@ -import { PrismaClient } from '@prisma/client'; +import { PrismaMariaDb } from '@prisma/adapter-mariadb'; +import { PrismaClient } from '../../src/prisma/types'; -const prisma = new PrismaClient(); +const prisma = new PrismaClient({ adapter: new PrismaMariaDb(process.env.DATABASE_URL) }); async function main() { console.info('\x1b[42;30mSeeding UE aliases\x1b[0m'); diff --git a/scripts/seed/base.ts b/scripts/seed/base.ts index 2dadf7e3..04edab44 100644 --- a/scripts/seed/base.ts +++ b/scripts/seed/base.ts @@ -1,6 +1,7 @@ -import { PrismaClient } from '@prisma/client'; +import { PrismaMariaDb } from '@prisma/adapter-mariadb'; +import { PrismaClient } from '../../src/prisma/types'; -const prisma = new PrismaClient(); +const prisma = new PrismaClient({ adapter: new PrismaMariaDb(process.env.DATABASE_URL) }); async function main() { // SEMESTERS // diff --git a/scripts/seed/ue.ts b/scripts/seed/ue.ts index 1f7063c3..3ecd2505 100644 --- a/scripts/seed/ue.ts +++ b/scripts/seed/ue.ts @@ -1,10 +1,11 @@ +import { PrismaMariaDb } from '@prisma/adapter-mariadb'; +import { PrismaClient } from '../../src/prisma/types'; import { createReadStream } from 'fs'; import { createInterface } from 'readline/promises'; import { parse } from '@fast-csv/parse'; -import { PrismaClient } from '@prisma/client'; -import '../../src/array'; +import '../../src/std.type'; -const prisma = new PrismaClient(); +const prisma = new PrismaClient({ adapter: new PrismaMariaDb(process.env.DATABASE_URL) }); type UEOF = { entry_nb: string; @@ -157,8 +158,8 @@ async function main() { 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), + ? ue.engineer_branch + : branches.filter((branch) => !branch.isMaster).map((branch) => branch.code), }); if (ue.master_credit_type) credits.push({ @@ -167,8 +168,8 @@ async function main() { 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), + ? ue.master_branch + : branches.filter((branch) => branch.isMaster).map((branch) => branch.code), }); if (ue.code === 'PE00') credits.push( @@ -330,7 +331,7 @@ async function main() { ), ); console.info('\x1b[42;30m✅ Import complete\x1b[0m'); - } catch (error) { + } catch { console.error( '\x1b[41;30mAn error occurred while importing UE requirements. Try `$ pnpm seed:ue:aliases` first.\x1b[0m', ); diff --git a/src/app.interceptor.ts b/src/app.interceptor.ts index 72614d17..15925cce 100644 --- a/src/app.interceptor.ts +++ b/src/app.interceptor.ts @@ -1,7 +1,7 @@ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'; import { map, Observable } from 'rxjs'; import { Request } from 'express'; -import { Language } from '@prisma/client'; +import { Language } from './prisma/types'; import { getTranslation } from './utils'; @Injectable() diff --git a/src/app.module.ts b/src/app.module.ts index a9b8f700..532dab92 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -15,12 +15,14 @@ import { BranchModule } from './branch/branch.module'; import { AssosModule } from './assos/assos.module'; import { TranslationInterceptor } from './app.interceptor'; import { SemesterModule } from './semester/semester.module'; +import { ImageMediaModule } from './media/image/imagemedia.module'; @Module({ imports: [ ConfigModule, HttpModule, PrismaModule, + ImageMediaModule, SemesterModule, AuthModule, ProfileModule, diff --git a/src/assos/assos.controller.ts b/src/assos/assos.controller.ts index f64ee5da..b416bf4e 100644 --- a/src/assos/assos.controller.ts +++ b/src/assos/assos.controller.ts @@ -2,6 +2,7 @@ import { Body, Controller, Delete, Get, Patch, Post, Put, Query } from '@nestjs/ import { ApiCreatedResponse, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; import { ApiAppErrorResponse, paginatedResponseDto } from '../app.dto'; import { AssoMembershipRole } from './interfaces/membership-role.interface'; +import { ImageMediaService } from '../media/image/imagemedia.service'; import { AssoMembership } from './interfaces/membership.interface'; import { ParamAsso } from './decorator/get-asso'; import { GetUser, IsPublic } from '../auth/decorator'; @@ -23,6 +24,9 @@ import AssosMemberCreateReqDto from './dto/req/assos-member-create.dto'; import AssosMemberUpdateReqDto from './dto/req/assos-member-update.dto'; import AssoMembershipResDto from './dto/res/assos-membership-res.dto'; import UsersService from '../users/users.service'; +import AssosUpdateReqDto from './dto/req/assos-update-req.dto'; +import { LexicalModule } from '../lexical/lexical.module'; +import { ImageMediaPreset } from '../prisma/types'; @Controller('assos') @ApiTags('Assos') @@ -30,6 +34,8 @@ export class AssosController { constructor( readonly assosService: AssosService, readonly userService: UsersService, + readonly mediaService: ImageMediaService, + readonly lexicalModule: LexicalModule, ) {} @Get() @@ -56,6 +62,39 @@ export class AssosController { return this.formatAssoDetail(asso); } + @Patch('/:assoId') + @ApiOperation({ + description: 'Update an asso. Only the fields present in the body will be updated.', + }) + @ApiOkResponse({ type: AssoDetailResDto }) + @ApiAppErrorResponse(ERROR_CODE.NO_SUCH_ASSO, 'There is no asso with the given id') + @ApiAppErrorResponse( + ERROR_CODE.FORBIDDEN_ASSOS_PERMISSIONS, + 'The user has no permission to perform this action for this asso', + ) + @ApiAppErrorResponse(ERROR_CODE.NO_SUCH_MEDIA, 'The media does not exist') + @ApiAppErrorResponse(ERROR_CODE.MEDIA_NOT_PUBLIC, 'The media is not public') + @ApiAppErrorResponse(ERROR_CODE.MEDIA_PRESET_REQUIRED, 'The media does not have the required preset (avatar)') + async updateAsso( + @ParamAsso() asso: Asso, + @GetUser() user: User, + @Body() body: AssosUpdateReqDto, + ): Promise { + if (!(await this.assosService.hasSomeAssoPermission(asso, user.id, 'manage_infos'))) + throw new AppException(ERROR_CODE.FORBIDDEN_ASSOS_PERMISSIONS, asso.id, 'manage_infos'); + for (const key in body.description) + if (body.description[key] && !this.lexicalModule.isValidLexicalContent(body.description[key])) + throw new AppException(ERROR_CODE.PARAM_LEXICAL_ILLEGAL, `description.${key}`); + if (body.logo) { + const media = await this.mediaService.getMedia(body.logo); + if (!media) throw new AppException(ERROR_CODE.NO_SUCH_MEDIA, body.logo); + if (!media.isPublic) throw new AppException(ERROR_CODE.MEDIA_NOT_PUBLIC); + if (media.preset !== ImageMediaPreset.AVATAR) + throw new AppException(ERROR_CODE.MEDIA_PRESET_REQUIRED, ImageMediaPreset.AVATAR); + } + return this.assosService.updateAsso(asso.id, body).then(this.formatAssoDetail); + } + // The route below is not public as it exposes the full name of all members, only the president is supposed to be exposed publicly in the route above @Get('/:assoId/members') @ApiOperation({ @@ -218,7 +257,8 @@ export class AssosController { formatAssoOverview(asso: Asso): AssoOverviewResDto { return { - ...pick(asso, 'id', 'name', 'logo', 'president'), + ...pick(asso, 'id', 'name', 'president'), + logo: asso.logo ? `/media/image/${asso.logo.id}.webp` : null, shortDescription: asso.descriptionShortTranslation, president: { role: pick(asso.president.role, 'id', 'name'), @@ -229,7 +269,8 @@ export class AssosController { formatAssoDetail(asso: Asso): AssoDetailResDto { return { - ...pick(asso, 'id', 'name', 'mail', 'phoneNumber', 'website', 'logo'), + ...pick(asso, 'id', 'name', 'mail', 'phoneNumber', 'website'), + logo: asso.logo ? `/media/image/${asso.logo.id}.webp` : null, description: asso.descriptionTranslation, president: { role: pick(asso.president.role, 'id', 'name'), diff --git a/src/assos/assos.module.ts b/src/assos/assos.module.ts index bd02ca10..ecbca011 100644 --- a/src/assos/assos.module.ts +++ b/src/assos/assos.module.ts @@ -1,6 +1,8 @@ import { Module } from '@nestjs/common'; import { AssosController } from './assos.controller'; import { AssosService } from './assos.service'; +import { ImageMediaModule } from '../media/image/imagemedia.module'; +import { LexicalModule } from '../lexical/lexical.module'; import UsersService from '../users/users.service'; /** @@ -10,5 +12,6 @@ import UsersService from '../users/users.service'; @Module({ controllers: [AssosController], providers: [AssosService, UsersService], + imports: [ImageMediaModule, LexicalModule], }) export class AssosModule {} diff --git a/src/assos/assos.service.ts b/src/assos/assos.service.ts index e21b02e0..6bd8bdab 100644 --- a/src/assos/assos.service.ts +++ b/src/assos/assos.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { Prisma } from '@prisma/client'; +import { Prisma } from '../prisma/types'; import { ConfigModule } from '../config/config.module'; import { PrismaService } from '../prisma/prisma.service'; import { RawAssoMembershipRole } from '../prisma/types'; @@ -9,6 +9,7 @@ import { AssoMembershipRole } from './interfaces/membership-role.interface'; import AssosSearchReqDto from './dto/req/assos-search-req.dto'; import AssosMemberUpdateReqDto from './dto/req/assos-member-update.dto'; import { AppException, ERROR_CODE } from '../exceptions'; +import AssosUpdateReqDto from './dto/req/assos-update-req.dto'; @Injectable() export class AssosService { @@ -81,6 +82,63 @@ export class AssosService { }); } + async updateAsso(assoId: string, update: AssosUpdateReqDto): Promise { + const updated = await this.prisma.normalize.asso.update({ + where: { id: assoId }, + data: { + ...(update.name ? { name: update.name } : {}), + ...(update.logo ? { logo: { connect: { id: update.logo } } } : {}), + ...(update.descriptionShort ? { descriptionShortTranslation: { update: update.descriptionShort } } : {}), + ...(update.description ? { descriptionTranslation: { update: update.description } } : {}), + ...(update.email ? { mail: update.email } : {}), + ...(update.phoneNumber ? { phoneNumber: update.phoneNumber } : {}), + ...(update.website ? { website: update.website } : {}), + }, + }); + if (update.description) { + // Cleanup unused images + const regex = /"src":"https:\/\/[^"]+\/media\/image\/([^/]+)\.webp"/g; + const imagesInUse = new Set(); + for (const field in updated.descriptionTranslation) + for (const match of (updated.descriptionTranslation[field])?.matchAll(regex) ?? []) + imagesInUse.add(match[1]); + const currentImages = new Set( + ( + await this.prisma.imageMedia.findMany({ + where: { descriptionForAssos: { some: { id: assoId } } }, + select: { id: true }, + }) + ).map((m) => m.id), + ); + const deletions = [...currentImages].filter((x) => !imagesInUse.has(x)); + const additions = [...imagesInUse].filter((x) => !currentImages.has(x)); + const existingAdditionIds = new Set( + ( + await this.prisma.imageMedia.findMany({ + where: { id: { in: additions } }, + select: { id: true }, + }) + ).map((m) => m.id), + ); + if (deletions.length > 0 || additions.length > 0) + await this.prisma.$transaction([ + ...Array.from(deletions).map((id) => + this.prisma.imageMedia.update({ + where: { id }, + data: { descriptionForAssos: { disconnect: { id: assoId } } }, + }), + ), + ...Array.from(additions.filter((x) => existingAdditionIds.has(x))).map((id) => + this.prisma.imageMedia.update({ + where: { id }, + data: { descriptionForAssos: { connect: { id: assoId } } }, + }), + ), + ]); + } + return updated; + } + async getAssoMembers(assoId: string): Promise { return this.prisma.normalize.assoMembershipRole.findMany({ where: { diff --git a/src/assos/dto/req/assos-update-req.dto.ts b/src/assos/dto/req/assos-update-req.dto.ts new file mode 100644 index 00000000..3307a6a6 --- /dev/null +++ b/src/assos/dto/req/assos-update-req.dto.ts @@ -0,0 +1,50 @@ +import { Type } from 'class-transformer'; +import { + IsEmail, + IsNotEmpty, + IsOptional, + IsPhoneNumber, + IsString, + IsUrl, + IsUUID, + ValidateNested, +} from 'class-validator'; +import { TranslatedTextDto } from '../../../utils'; + +export default class AssosUpdateReqDto { + @IsOptional() + @IsString() + @IsNotEmpty() + name?: string; + + @IsOptional() + @IsString() + @IsNotEmpty() + @IsUUID() + logo?: string; + + @IsOptional() + @Type(() => TranslatedTextDto) + @ValidateNested() + descriptionShort?: TranslatedTextDto; + + @IsOptional() + @Type(() => TranslatedTextDto) + @ValidateNested() + description?: TranslatedTextDto; + + @IsOptional() + @IsString() + @IsEmail() + email?: string; + + @IsOptional() + @IsString() + @IsPhoneNumber() + phoneNumber?: string; + + @IsOptional() + @IsString() + @IsUrl() + website?: string; +} diff --git a/src/assos/interfaces/asso.interface.ts b/src/assos/interfaces/asso.interface.ts index 7d93385f..f2cf7fe2 100644 --- a/src/assos/interfaces/asso.interface.ts +++ b/src/assos/interfaces/asso.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../prisma/types'; import { generateCustomModel } from '../../prisma/prisma.service'; import { translationSelect } from '../../utils'; diff --git a/src/assos/interfaces/membership-role.interface.ts b/src/assos/interfaces/membership-role.interface.ts index dd1fc7fe..ff582da8 100644 --- a/src/assos/interfaces/membership-role.interface.ts +++ b/src/assos/interfaces/membership-role.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../prisma/types'; import { generateCustomModel } from '../../prisma/prisma.service'; const ASSO_MEMBERSHIPROLE_SELECT_FILTER = { diff --git a/src/assos/interfaces/membership.interface.ts b/src/assos/interfaces/membership.interface.ts index 2dc367fe..e019df83 100644 --- a/src/assos/interfaces/membership.interface.ts +++ b/src/assos/interfaces/membership.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../prisma/types'; import { generateCustomModel } from '../../prisma/prisma.service'; const ASSO_MEMBERSHIP_SELECT_FILTER = { diff --git a/src/auth/application/application.controller.ts b/src/auth/application/application.controller.ts index ad905485..5ccd954d 100644 --- a/src/auth/application/application.controller.ts +++ b/src/auth/application/application.controller.ts @@ -10,7 +10,7 @@ import { PermissionManager, pick } from '../../utils'; import AuthTokenResDto from '../dto/res/auth-token-res.dto'; import { GetPermissions } from '../decorator/get-permissions.decorator'; import { AppException, ERROR_CODE } from '../../exceptions'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../prisma/types'; import ApplicationClientSecretResDto from './dto/res/application-client-secret-res.dto'; import { ApiAppErrorResponse } from '../../app.dto'; import ApplicationSensibleResDto from './dto/res/application-sensible-res.dto'; diff --git a/src/auth/application/interfaces/application.interface.ts b/src/auth/application/interfaces/application.interface.ts index f100ebe5..5af7e4ad 100644 --- a/src/auth/application/interfaces/application.interface.ts +++ b/src/auth/application/interfaces/application.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../../prisma/types'; import { generateCustomModel } from '../../../prisma/prisma.service'; const APPLICATION_SELECT_FILTER = { @@ -23,5 +23,10 @@ const APPLICATION_SELECT_FILTER = { export type Application = Prisma.ApiApplicationGetPayload; export function generateCustomApplicationModel(prisma: PrismaClient) { - return generateCustomModel(prisma, 'apiApplication', APPLICATION_SELECT_FILTER, (_, application: Application) => application); + return generateCustomModel( + prisma, + 'apiApplication', + APPLICATION_SELECT_FILTER, + (_, application: Application) => application, + ); } diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index a42ad82f..33944e12 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import * as bcrypt from 'bcryptjs'; -import { Prisma, UserType } from '@prisma/client'; +import { Prisma, UserType } from '../prisma/types'; import { JwtService } from '@nestjs/jwt'; import { AppException, ERROR_CODE } from '../exceptions'; import { ConfigModule } from '../config/config.module'; diff --git a/src/auth/decorator/index.ts b/src/auth/decorator/index.ts index 4b609c58..90ff7cc2 100644 --- a/src/auth/decorator/index.ts +++ b/src/auth/decorator/index.ts @@ -2,3 +2,4 @@ export * from './get-user.decorator'; export * from './require-permission.decorator'; export * from './public.decorator'; export * from './require-role.decorator'; +export * from './skip-application-check.decorator'; diff --git a/src/auth/decorator/require-role.decorator.ts b/src/auth/decorator/require-role.decorator.ts index 2014a8ee..98f832e1 100644 --- a/src/auth/decorator/require-role.decorator.ts +++ b/src/auth/decorator/require-role.decorator.ts @@ -1,6 +1,6 @@ import { ExecutionContext, SetMetadata } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; -import { UserType } from '@prisma/client'; +import { UserType } from '../../prisma/types'; export const REQUIRED_USER_TYPES_KEY = 'requiredUserTypes'; /** diff --git a/src/auth/decorator/skip-application-check.decorator.ts b/src/auth/decorator/skip-application-check.decorator.ts new file mode 100644 index 00000000..3b13bef1 --- /dev/null +++ b/src/auth/decorator/skip-application-check.decorator.ts @@ -0,0 +1,3 @@ +import { Reflector } from '@nestjs/core'; + +export const SkipApplicationCheck = Reflector.createDecorator(); diff --git a/src/auth/dto/req/auth-sign-up-req.dto.ts b/src/auth/dto/req/auth-sign-up-req.dto.ts index 47920881..cf69fe4b 100644 --- a/src/auth/dto/req/auth-sign-up-req.dto.ts +++ b/src/auth/dto/req/auth-sign-up-req.dto.ts @@ -1,7 +1,7 @@ import { IsAlphanumeric, IsDate, IsEnum, IsNotEmpty, IsNumber, IsOptional, IsString } from 'class-validator'; import { IsPositive } from 'class-validator'; import { Type } from 'class-transformer'; -import { Sex } from '@prisma/client'; +import { Sex } from '../../../prisma/types'; import { ApiProperty } from '@nestjs/swagger'; export default class AuthSignUpReqDto { diff --git a/src/auth/guard/jwt.guard.ts b/src/auth/guard/jwt.guard.ts index 43eb79e0..5235efb7 100644 --- a/src/auth/guard/jwt.guard.ts +++ b/src/auth/guard/jwt.guard.ts @@ -1,27 +1,33 @@ import { ExecutionContext, Injectable } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; -import { IsPublic } from '../decorator'; +import { IsPublic, SkipApplicationCheck } from '../decorator'; import { AppException, ERROR_CODE } from '../../exceptions'; import { RequestAuthData } from '../interfaces/request-auth-data.interface'; import { PrismaService } from '../../prisma/prisma.service'; import { PermissionManager } from '../../utils'; +import { RawApiApplication } from '../../prisma/types'; @Injectable() export class JwtGuard extends AuthGuard('jwt') { - constructor(private reflector: Reflector, private prisma: PrismaService) { + constructor( + private reflector: Reflector, + private prisma: PrismaService, + ) { super(); } async canActivate(context: ExecutionContext) { const request = context.switchToHttp().getRequest() as { user: RequestAuthData }; + const canSkipApplicationHeader = this.reflector.get(SkipApplicationCheck, context.getHandler()); const applicationId = context.switchToHttp().getRequest().headers['x-application']; - if (!applicationId) throw new AppException(ERROR_CODE.APPLICATION_HEADER_MISSING); - const application = await this.prisma.apiApplication.findUnique({ - where: { id: applicationId }, - }); - if (!application) { - throw new AppException(ERROR_CODE.NO_SUCH_APPLICATION, applicationId); + let application: RawApiApplication | null = null; + if (!applicationId && !canSkipApplicationHeader) throw new AppException(ERROR_CODE.APPLICATION_HEADER_MISSING); + else if (applicationId) { + application = await this.prisma.apiApplication.findUnique({ + where: { id: applicationId }, + }); + if (!application) throw new AppException(ERROR_CODE.NO_SUCH_APPLICATION, applicationId); } // Check whether the user is logged in let loggedIn = true; diff --git a/src/auth/interfaces/permissions.interface.ts b/src/auth/interfaces/permissions.interface.ts index 789eb651..d7a95dc7 100644 --- a/src/auth/interfaces/permissions.interface.ts +++ b/src/auth/interfaces/permissions.interface.ts @@ -1,4 +1,4 @@ -import { Permission } from '@prisma/client'; +import { Permission } from '../../prisma/types'; export type ApiPermission = Permission & `API_${string}`; export type UserPermission = Permission & `USER_${string}`; diff --git a/src/auth/permissions/dto/res/permissions.dto.ts b/src/auth/permissions/dto/res/permissions.dto.ts index 7280be7b..558e2800 100644 --- a/src/auth/permissions/dto/res/permissions.dto.ts +++ b/src/auth/permissions/dto/res/permissions.dto.ts @@ -1,5 +1,5 @@ import { UserPermission } from '../../../interfaces/permissions.interface'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../../../prisma/types'; export default class PermissionsResDto { hardPermissions: Permission[]; diff --git a/src/branch/interface/branch.interface.ts b/src/branch/interface/branch.interface.ts index da94ddfc..00799fd0 100644 --- a/src/branch/interface/branch.interface.ts +++ b/src/branch/interface/branch.interface.ts @@ -1,4 +1,4 @@ -import { Prisma } from '@prisma/client'; +import { Prisma } from '../../prisma/types'; const BRANCH_SELECT_FILTER = { select: { diff --git a/src/config/config.module.ts b/src/config/config.module.ts index 614c5b39..75245e5e 100644 --- a/src/config/config.module.ts +++ b/src/config/config.module.ts @@ -31,6 +31,8 @@ export class ConfigModule { public readonly IS_PROD_ENV: boolean; public readonly TIMETABLE_URL: string; public readonly ANNAL_UPLOAD_DIR: string; + public readonly MEDIA_UPLOAD_DIR: string; + public readonly MEDIA_DETACHED_LIFESPAN: number; public readonly ETUUTT_WEBSITE_APPLICATION_ID: string; // DEV ENVIRONMENT ONLY @@ -49,10 +51,13 @@ export class ConfigModule { this.LDAP_USER = config.get('LDAP_USER'); this.LDAP_PWD = config.get('LDAP_PWD'); this.ANNAL_UPLOAD_DIR = config.get('ANNAL_UPLOAD_DIR'); + this.MEDIA_UPLOAD_DIR = config.get('MEDIA_UPLOAD_DIR'); + this.MEDIA_DETACHED_LIFESPAN = Number(config.get('MEDIA_DETACHED_LIFESPAN')); this.IS_PROD_ENV = isProdEnv; this.TIMETABLE_URL = config.get('TIMETABLE_URL'); if (this.ANNAL_UPLOAD_DIR.endsWith('/')) this.ANNAL_UPLOAD_DIR = this.ANNAL_UPLOAD_DIR.slice(0, -1); + if (this.MEDIA_UPLOAD_DIR.endsWith('/')) this.MEDIA_UPLOAD_DIR = this.MEDIA_UPLOAD_DIR.slice(0, -1); this.ETUUTT_WEBSITE_APPLICATION_ID = config.get('ETUUTT_WEBSITE_APPLICATION_ID'); this._FAKER_SEED = isTestEnv ? Number(config.get('FAKER_SEED')) : undefined; diff --git a/src/exceptions.ts b/src/exceptions.ts index 28c17707..f8296ea2 100644 --- a/src/exceptions.ts +++ b/src/exceptions.ts @@ -40,6 +40,7 @@ export const enum ERROR_CODE { BODY_MISSING = 2022, PARAM_PAST_DATE = 2023, PARAM_MISSING_EITHER = 2024, + PARAM_LEXICAL_ILLEGAL = 2101, PARAM_DOES_NOT_MATCH_REGEX = 2102, NO_FIELD_PROVIDED = 2201, WIDGET_OVERLAPPING = 2301, @@ -68,6 +69,8 @@ export const enum ERROR_CODE { NOT_ALREADY_DONE_UEOF = 4229, APPLICATION_NOT_OWNED = 4230, USER_ALREADY_ASSO_ROLE_MEMBER = 4231, + MEDIA_NOT_PUBLIC = 4232, + MEDIA_PRESET_REQUIRED = 4233, NO_SUCH_UE = 4401, NO_SUCH_COMMENT = 4402, NO_SUCH_REPLY = 4403, @@ -84,11 +87,13 @@ export const enum ERROR_CODE { NO_SUCH_UE_AT_SEMESTER = 4414, NO_SUCH_ASSO_ROLE = 4415, NO_SUCH_ASSO_MEMBERSHIP = 4416, + NO_SUCH_MEDIA = 4417, ANNAL_ALREADY_UPLOADED = 4901, RESOURCE_UNAVAILABLE = 4902, RESOURCE_INVALID_TYPE = 4903, ASSO_ROLE_ALREADY_MOVED = 4904, CREDENTIALS_ALREADY_TAKEN = 5001, + SERVER_DISK_ERROR = 8001, HIDDEN_DUCK = 9999, } @@ -206,6 +211,10 @@ export const ErrorData = Object.freeze({ message: 'One of these parameters must be provided: %', httpCode: HttpStatus.BAD_REQUEST, }, + [ERROR_CODE.PARAM_LEXICAL_ILLEGAL]: { + message: 'Content has a wrong syntax: %', + httpCode: HttpStatus.BAD_REQUEST, + }, [ERROR_CODE.PARAM_DOES_NOT_MATCH_REGEX]: { message: 'The following parameters must match the regex "%": %', httpCode: HttpStatus.BAD_REQUEST, @@ -318,6 +327,14 @@ export const ErrorData = Object.freeze({ message: 'User is already member of this role: %', httpCode: HttpStatus.CONFLICT, }, + [ERROR_CODE.MEDIA_NOT_PUBLIC]: { + message: 'Media must be public', + httpCode: HttpStatus.FORBIDDEN, + }, + [ERROR_CODE.MEDIA_PRESET_REQUIRED]: { + message: 'Media must have preset %', + httpCode: HttpStatus.FORBIDDEN, + }, [ERROR_CODE.NO_SUCH_UE]: { message: 'The UE % does not exist', httpCode: HttpStatus.NOT_FOUND, @@ -382,6 +399,10 @@ export const ErrorData = Object.freeze({ message: 'No such membership in asso: %', httpCode: HttpStatus.NOT_FOUND, }, + [ERROR_CODE.NO_SUCH_MEDIA]: { + message: 'No such media: %', + httpCode: HttpStatus.NOT_FOUND, + }, [ERROR_CODE.ANNAL_ALREADY_UPLOADED]: { message: 'A file has alreay been uploaded for this annal', httpCode: HttpStatus.CONFLICT, @@ -402,6 +423,10 @@ export const ErrorData = Object.freeze({ message: 'You should not try to update role position simultaneously', httpCode: HttpStatus.CONFLICT, }, + [ERROR_CODE.SERVER_DISK_ERROR]: { + message: 'An error occurred while accessing the server disk', + httpCode: HttpStatus.SERVICE_UNAVAILABLE, + }, [ERROR_CODE.HIDDEN_DUCK]: { message: 'Hey, you found the hidden duck ! Error : %', httpCode: HttpStatus.I_AM_A_TEAPOT, diff --git a/src/lexical/lexical.module.ts b/src/lexical/lexical.module.ts new file mode 100644 index 00000000..2d36b682 --- /dev/null +++ b/src/lexical/lexical.module.ts @@ -0,0 +1,133 @@ +import { Module } from '@nestjs/common'; +import { TextNode, ParagraphNode } from 'lexical'; +import { createHeadlessEditor } from '@lexical/headless'; +import { $generateHtmlFromNodes } from '@lexical/html'; +import { AutoLinkNode, LinkNode } from '@lexical/link'; +import { HeadingNode, QuoteNode } from '@lexical/rich-text'; +import { CodeHighlightNode, CodeNode } from '@lexical/code'; +import { TableNode, TableCellNode, TableRowNode } from '@lexical/table'; +import { ListNode, ListItemNode } from '@lexical/list'; +import { HorizontalRuleNode } from '@lexical/extension'; +import { ColorTextNode, ImageNode, RegisteredStyleMap } from './nodes'; +import { patchNodeExportDOM } from './nodes/NodeStyleInjector'; + +/** @internal */ +export const BUNDLES = { + '@etuutt/simple': [], + '@etuutt/full': [ + AutoLinkNode, + CodeHighlightNode, + CodeNode, + ColorTextNode, + HeadingNode, + HorizontalRuleNode, + ImageNode, + LinkNode, + ListItemNode, + ListNode, + TableCellNode, + TableNode, + TableRowNode, + QuoteNode, + ], +}; + +@Module({ + exports: [LexicalModule], +}) +export class LexicalModule { + constructor() { + [TextNode, ParagraphNode, ...BUNDLES['@etuutt/full']].forEach(patchNodeExportDOM); + } + + /** + * Validates the user-provided string as valid Lexical content. Checks both structure and content. + * + * Checks that the content only contains nodes from the provided bundle (you can define custom bundles in {@link BUNDLES}). + * This check is performed by parsing the content and re-serializing it, then comparing the result to the original input. + * This forbids the use of unknown nodes as well as unknown properties. However, the client implementation is supposed to + * serialize nodes the same way as the API does so that properties are in the same order. + * + * @param userInput the string provided by the user + * @param bundle the bundle of allowed nodes (default: full bundle) + * @returns true if the content is valid, false otherwise + */ + isValidLexicalContent(userInput: string, bundle: keyof typeof BUNDLES = '@etuutt/full') { + try { + const editor = createHeadlessEditor({ + nodes: BUNDLES[bundle], + onError: () => {}, + }); + const parsed = JSON.parse(userInput); + const editorState = editor.parseEditorState(parsed); + return JSON.stringify(editorState.toJSON()) === userInput; + } catch { + return false; + } + } + + /** + * Generates HTML from lexical content. Nodes not in included the bundle are ignored. The output is sanitized (by happy-dom) and + * contains inline-styles instead of classes, for email use. Inline style is defined in the {@link CustomStyles} (./nodes/index.ts). + * + * This function can not be used in a jest context as it relies on happy-dom to provide a DOM implementation. + * + * @param lexicalContent the lexical content to convert + * @param bundle the bundle of allowed nodes (default: full bundle) + * @returns the generated HTML + */ + async generateHTML(lexicalContent: string, bundle: keyof typeof BUNDLES = '@etuutt/full'): Promise { + let html = ''; + const { withDOM } = (await new Function( + "return import('@lexical/headless/dom')", + )()) as typeof import('@lexical/headless/dom'); + withDOM(() => { + const editor = createHeadlessEditor({ + nodes: BUNDLES[bundle], + theme: { + image: 'editor-image', + link: 'editor-link', + text: { + bold: 'editor-bold', + italic: 'editor-italic', + underline: 'editor-underline', + strikethrough: 'editor-strikethrough', + code: 'editor-code', + }, + paragraph: 'editor-no-margin', + heading: { + h1: 'editor-h1', + h2: 'editor-h2', + h3: 'editor-no-margin', + h4: 'editor-no-margin', + h5: 'editor-no-margin', + h6: 'editor-no-margin', + }, + quote: 'editor-quote', + hr: 'editor-horizontal-rule', + list: { + checklist: 'editor-checklist', + listitem: 'editor-list-item', + listitemChecked: 'editor-list-item-checked', + listitemUnchecked: 'editor-list-item-unchecked', + ol: 'editor-ordered-list', + ul: 'editor-unordered-list', + nested: { + listitem: 'editor-list-item-nested', + }, + }, + table: 'editor-table', + tableCell: 'editor-table-cell', + tableCellHeader: 'editor-table-cell-header', + tableRow: 'editor-table-row', + } satisfies RegisteredStyleMap, + }); + const parsed = JSON.parse(lexicalContent); + editor.setEditorState(editor.parseEditorState(parsed)); + editor.read(() => (html = $generateHtmlFromNodes(editor))); + }); + return html + .replaceAll('class=""', '') + .replaceAll(/(?<=<[^>]+)(?]*>)|(?<=<[^>]*(?:\w|"))\s+(?=>)/g, ''); + } +} diff --git a/src/lexical/nodes/ColorTextNode.ts b/src/lexical/nodes/ColorTextNode.ts new file mode 100644 index 00000000..422c30f8 --- /dev/null +++ b/src/lexical/nodes/ColorTextNode.ts @@ -0,0 +1,63 @@ +import { + $getState, + $setState, + createState, + DOMConversionMap, + DOMExportOutput, + LexicalEditor, + NodeKey, + SerializedTextNode, + Spread, + TextNode, +} from 'lexical'; + +const ColorOptions = { blue: '#2d8fce', darkblue: '#1b557a', grey: '#444c5f', darkgrey: '#2e3442' }; +export type ColorType = keyof typeof ColorOptions; + +type SerializedColorTextNode = Spread<{ color?: ColorType }, SerializedTextNode>; + +const colorState = createState('color', { + parse: (v) => ((v as ColorType) in ColorOptions ? (v as ColorType) : undefined), +}); + +export class ColorTextNode extends TextNode { + static getType() { + return 'color-text'; + } + + static clone(node: ColorTextNode) { + return new ColorTextNode(node.__text, node.__key); + } + + setColor(color?: ColorType) { + $setState(this, colorState, color); + return this; + } + + static importJSON(serializedNode: SerializedColorTextNode): ColorTextNode { + return $createColorTextNode(serializedNode.text).updateFromJSON(serializedNode).setColor(serializedNode.color); + } + + exportJSON(): SerializedColorTextNode { + return { + ...super.exportJSON(), + color: $getState(this, colorState), + $: undefined, + }; + } + + exportDOM(editor: LexicalEditor): DOMExportOutput { + const { element } = super.exportDOM(editor); + const color = $getState(this, colorState); + if (color) (element as HTMLElement).style.color = ColorOptions[color]; + return { element }; + } + + static importDOM(): DOMConversionMap { + return null; + } +} + +export function $createColorTextNode(text?: string, nodeKey?: NodeKey): ColorTextNode { + return new ColorTextNode(text, nodeKey); +} diff --git a/src/lexical/nodes/ImageNode.ts b/src/lexical/nodes/ImageNode.ts new file mode 100644 index 00000000..966aca5f --- /dev/null +++ b/src/lexical/nodes/ImageNode.ts @@ -0,0 +1,87 @@ +import { + DecoratorNode, + DOMConversionMap, + DOMExportOutput, + LexicalEditor, + NodeKey, + SerializedLexicalNode, + Spread, +} from 'lexical'; + +type SerializedImageNode = Spread< + { + src: string; + altText: string; + width: number | 'inherit'; + height: number | 'inherit'; + }, + SerializedLexicalNode +>; + +export class ImageNode extends DecoratorNode { + __src: string; + __altText: string; + __width: number | 'inherit'; + __height: number | 'inherit'; + + static getType() { + return 'image'; + } + + static clone(node: ImageNode) { + return new ImageNode(node.__src, node.__altText, node.__width, node.__height, node.__key); + } + + constructor(src: string, altText?: string, width?: number | 'inherit', height?: number | 'inherit', key?: NodeKey) { + super(key); + this.__src = src; + this.__altText = altText || ''; + this.__width = width || 'inherit'; + this.__height = height || 'inherit'; + } + + exportDOM(editor: LexicalEditor): DOMExportOutput { + const element = document.createElement('span'); + if (editor._config?.theme?.image) element.className = editor._config.theme.image; + const img = document.createElement('img'); + img.src = this.__src; + img.alt = this.__altText; + if (this.__width !== 'inherit') img.width = this.__width; + if (this.__height !== 'inherit') img.height = this.__height; + element.appendChild(img); + return { element }; + } + + static importJSON(serializedNode: SerializedImageNode): ImageNode { + return $createImageNode( + serializedNode.src, + serializedNode.altText, + serializedNode.width, + serializedNode.height, + ).updateFromJSON(serializedNode); + } + + exportJSON(): SerializedImageNode { + return { + ...super.exportJSON(), + src: this.__src, + altText: this.__altText, + width: this.__width, + height: this.__height, + }; + } + + static importDOM(): DOMConversionMap { + return null; + } +} + +export function $createImageNode( + src: string, + altText?: string, + width?: number | 'inherit', + height?: number | 'inherit', + nodeKey?: NodeKey, +): ImageNode { + return new ImageNode(src, altText, width, height, nodeKey); +} diff --git a/src/lexical/nodes/NodeStyleInjector.ts b/src/lexical/nodes/NodeStyleInjector.ts new file mode 100644 index 00000000..cc257900 --- /dev/null +++ b/src/lexical/nodes/NodeStyleInjector.ts @@ -0,0 +1,61 @@ +import { CodeHighlightNode } from '@lexical/code'; +import { TableCellNode } from '@lexical/table'; +import { LexicalNode } from 'lexical'; +import { CustomStyles } from '.'; + +/** Applies style to a specific Node */ +function applyStylesToElement(element: HTMLElement, index: number, node?: LexicalNode) { + element.classList.forEach((cName) => { + if (!(cName in CustomStyles)) return; + if (cName === 'editor-list-item-checked' || cName === 'editor-list-item-unchecked') + Object.assign(element.style, CustomStyles['editor-list-item-check-base']); + else if (cName !== 'editor-table-row' || !(index % 2)) + Object.assign(cName === 'editor-image' ? element.querySelector('img').style : element.style, CustomStyles[cName]); + if (cName === 'editor-table-cell-header' && node instanceof TableCellNode) + element.style.textAlign = node.__verticalAlign; + if (cName === 'editor-list-item-checked' || cName === 'editor-list-item-unchecked') { + const prependedElement = document.createElement('div'); + Object.assign(prependedElement.style, CustomStyles[cName]); + if (cName === 'editor-list-item-checked') { + const iconElement = document.createElement('div'); + Object.assign(iconElement.style, CustomStyles['editor-list-item-checked-icon']); + prependedElement.prepend(iconElement); + } + element.prepend(prependedElement); + } + }); + if (!element.className.includes('editor-ordered-list') && !element.className.includes('editor-unordered-list')) + element.className = ''; +} + +/** + * Patches the exportDOM method of a Lexical Node to inject inline styles based on class names. + */ +export function patchNodeExportDOM( + NodeClass: new (...args: unknown[]) => T extends (infer U)[] ? U : never, +) { + const original = NodeClass.prototype.exportDOM; + + NodeClass.prototype.exportDOM = function (this: LexicalNode, ...args: unknown[]) { + const result = original.apply(this, args); + const originalAfterFunction = result?.after; + result.after = (element: HTMLElement | null) => { + let updatedElement = element; + if (originalAfterFunction) updatedElement = originalAfterFunction(element); + applyStylesToElement(updatedElement, this.getIndexWithinParent(), this); + updatedElement + .querySelectorAll('[class]') + .forEach((element: HTMLElement) => + applyStylesToElement(element, Array.prototype.indexOf.call(element.parentElement.children, element)), + ); + }; + + return result; + }; + // Remove warning of having no importDOM method + if ((NodeClass as unknown) === CodeHighlightNode) { + Object.defineProperty(NodeClass, 'importDOM', { + value: () => null, + }); + } +} diff --git a/src/lexical/nodes/index.ts b/src/lexical/nodes/index.ts new file mode 100644 index 00000000..48492699 --- /dev/null +++ b/src/lexical/nodes/index.ts @@ -0,0 +1,151 @@ +import type { EditorThemeClasses } from 'lexical'; +export { ColorTextNode } from './ColorTextNode'; +export { ImageNode } from './ImageNode'; +import './NodeStyleInjector'; + +export type RegisteredStyleMap = { + [K1 in keyof EditorThemeClasses]: EditorThemeClasses[K1] extends Record + ? { + [K2 in keyof EditorThemeClasses[K1]]: EditorThemeClasses[K1][K2] extends Record + ? { [K3 in keyof EditorThemeClasses[K1][K2]]: keyof typeof CustomStyles } + : keyof typeof CustomStyles; + } + : keyof typeof CustomStyles; +}; + +/** + * Style to apply to elements of lexical content during HTML export. + * Every key represents a class name that can be applied to lexical nodes. + */ +export const CustomStyles = { + 'editor-image': { + maxWidth: '100%', + maxHeight: '100%', + height: 'auto', + borderRadius: '3px', + backgroundColor: 'rgba(68, 76, 95, 0.5)', + }, + 'editor-link': { + color: '#2d8fce', + borderBottom: '1px solid #2d8fce', + textDecoration: 'none', + }, + 'editor-bold': { + fontWeight: 'bold', + }, + 'editor-italic': { + fontStyle: 'italic', + }, + 'editor-underline': { + textDecoration: 'underline', + }, + 'editor-strikethrough': { + textDecoration: 'line-through', + }, + 'editor-code': { + backgroundColor: 'rgba(46, 52, 66, 0.1)', + borderRadius: '3px', + }, + 'editor-quote': { + backgroundColor: 'rgba(46, 52, 66, 0.1)', + margin: '0.5em', + padding: '0.5em', + borderLeft: '5px solid #2e3442', + borderRadius: '0 5px 5px 0', + }, + 'editor-horizontal-rule': { + border: 'none', + borderTop: '2px solid #2e3442', + margin: '1em 0', + }, + 'editor-no-margin': { + margin: '0', + }, + 'editor-h1': { + textTransform: 'uppercase', + fontWeight: '900', + margin: '0', + }, + 'editor-h2': { + fontWeight: 'bold', + margin: '0', + }, + 'editor-checklist': { + marginLeft: '-1.5em', + }, + 'editor-list-item': { + position: 'relative', + }, + 'editor-list-item-nested': { + listStyleType: 'none', + }, + 'editor-list-item-check-base': { + position: 'relative', + marginLeft: '0.5em', + marginRight: '0.5em', + paddingLeft: '1.5em', + paddingRight: '1.5em', + outline: 'none', + display: 'block', + }, + 'editor-list-item-checked': { + width: '0.9em', + height: '0.9em', + top: '50%', + left: '0', + display: 'block', + backgroundSize: 'cover', + position: 'absolute', + transform: 'translateY(-50%)', + border: '1px solid #2d8fce', + borderRadius: '2px', + backgroundColor: '#2d8fce', + backgroundRepeat: 'no-repeat', + }, + 'editor-list-item-checked-icon': { + borderColor: '#fafbfc', + borderStyle: 'solid', + position: 'absolute', + display: 'block', + top: '45%', + width: '0.2em', + left: '0.32em', + height: '0.4em', + transform: 'translateY(-50%) rotate(45deg)', + borderWidth: '0 0.1em 0.1em 0', + }, + 'editor-list-item-unchecked': { + width: '0.9em', + height: '0.9em', + top: '50%', + left: '0', + display: 'block', + backgroundSize: 'cover', + position: 'absolute', + transform: 'translateY(-50%)', + border: '1px solid rgba(68, 76, 95, 0.5)', + borderRadius: '2px', + }, + 'editor-ordered-list': { + paddingTop: '0', + }, + 'editor-unordered-list': { + paddingTop: '0', + }, + 'editor-table': { + borderCollapse: 'collapse', + }, + 'editor-table-cell': { + padding: '3px 4px', + minWidth: '200px', + border: '1px solid rgba(68, 76, 95, 0.3)', + }, + 'editor-table-cell-header': { + backgroundColor: '#2e3442', + color: '#fafbfc', + border: '1px solid #2e3442', + }, + 'editor-table-row': { + backgroundColor: 'rgba(68, 76, 95, 0.1)', + }, +} satisfies Record>; diff --git a/src/media/image/dto/req/imagemedia-upload-req.dto.ts b/src/media/image/dto/req/imagemedia-upload-req.dto.ts new file mode 100644 index 00000000..4682bb46 --- /dev/null +++ b/src/media/image/dto/req/imagemedia-upload-req.dto.ts @@ -0,0 +1,51 @@ +import { ImageMediaPreset } from '../../../../prisma/types'; +import { Type } from 'class-transformer'; +import { IsBoolean, IsEnum, IsInt, IsOptional, IsString, Max, Min } from 'class-validator'; + +export default class ImageMediaUploadReqDto { + @IsOptional() + @IsInt() + @Min(100) + @Max(1920) + @Type(() => Number) + width?: number; + + @IsOptional() + @IsInt() + @Min(100) + @Max(1080) + @Type(() => Number) + height?: number; + + @IsOptional() + @IsInt() + @Min(1) + @Max(100) + @Type(() => Number) + quality?: number; + + @IsOptional() + @IsInt() + @Min(0) + @Max(6) + @Type(() => Number) + effort?: number; + + @IsOptional() + @IsInt() + @Min(0) + @Max(3) + @Type(() => Number) + rotation?: 0 | 1 | 2 | 3; + + @IsOptional() + @IsString() + @IsEnum(ImageMediaPreset) + preset?: ImageMediaPreset; + + /** By default, images are NOT public and only accessible to logged users. */ + @IsOptional() + @IsBoolean() + @Type(() => Boolean) + public?: boolean; +} diff --git a/src/media/image/dto/res/imagemedia-upload-res.dto.ts b/src/media/image/dto/res/imagemedia-upload-res.dto.ts new file mode 100644 index 00000000..c4fc4ecf --- /dev/null +++ b/src/media/image/dto/res/imagemedia-upload-res.dto.ts @@ -0,0 +1,10 @@ +import { ImageMediaPreset } from '../../../../prisma/types'; + +export default class ImageMediaUploadResDto { + id: string; + width: number; + height: number; + size: number; + isPublic: boolean; + preset: ImageMediaPreset; +} diff --git a/src/media/image/imagemedia.controller.ts b/src/media/image/imagemedia.controller.ts new file mode 100644 index 00000000..6141ed9f --- /dev/null +++ b/src/media/image/imagemedia.controller.ts @@ -0,0 +1,69 @@ +import { Controller, Get, Post, Query, Response } from '@nestjs/common'; +import { ApiConsumes, ApiCreatedResponse, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; +import { Response as ExpressResponse } from 'express'; +import { FileSize, MulterWithMime, UploadRoute, UserFile } from '../../upload.interceptor'; +import { GetUser, IsPublic, RequireApiPermission, SkipApplicationCheck } from '../../auth/decorator'; +import { AppException, ERROR_CODE } from '../../exceptions'; +import { ApiAppErrorResponse } from '../../app.dto'; +import { ImageMediaService } from './imagemedia.service'; +import { UUIDParam } from '../../app.pipe'; +import { omit } from '../../utils'; +import { User } from '../../users/interfaces/user.interface'; +import ImageMediaUploadReqDto from './dto/req/imagemedia-upload-req.dto'; +import ImageMediaUploadResDto from './dto/res/imagemedia-upload-res.dto'; + +@Controller('media/image') +@ApiTags('Media') +export class ImageMediaController { + constructor(readonly imageMediaService: ImageMediaService) {} + + @Get('/:mediaId.webp') + @SkipApplicationCheck() + @IsPublic() + @ApiOperation({ description: 'Retrieve a media by its id.' }) + @ApiOkResponse({ description: 'The media is contained in the body of the response' }) + @ApiAppErrorResponse(ERROR_CODE.NO_SUCH_MEDIA, 'There is no media with the given id') + @ApiAppErrorResponse(ERROR_CODE.NOT_LOGGED_IN, 'This media is not public and requires authentication') + @ApiAppErrorResponse(ERROR_CODE.SERVER_DISK_ERROR, 'An error occurred while reading from disk') + async getMedia(@UUIDParam('mediaId') mediaId: string, @GetUser() user: User, @Response() response: ExpressResponse) { + const media = await this.imageMediaService.getMedia(mediaId); + if (!media) throw new AppException(ERROR_CODE.NO_SUCH_MEDIA, mediaId); + if (!media.isPublic && !user) throw new AppException(ERROR_CODE.NOT_LOGGED_IN); + const stream = this.imageMediaService.readMediaFromDisk(mediaId); + response.setHeader('Content-Type', 'image/webp'); + response.setHeader('Cache-Control', `${media.isPublic ? 'public' : 'private'}, max-age=31536000, immutable`); // 1 year + stream.pipe(response); + stream.on('error', () => { + stream.close(); + const exception = new AppException(ERROR_CODE.SERVER_DISK_ERROR); + response.status(exception.getStatus()).json(exception.getResponse()); + }); + } + + @Post('/') + @RequireApiPermission('API_UPLOAD_MEDIA') + @UploadRoute('file') + @ApiConsumes('image/png', 'image/jpeg', 'image/webp', 'image/avif', 'image/tiff') + @ApiOperation({ description: 'Uploads a media and returns its id.' }) + @ApiCreatedResponse({ type: ImageMediaUploadResDto }) + @ApiAppErrorResponse(ERROR_CODE.FORBIDDEN_NOT_ENOUGH_API_PERMISSIONS, 'The permission is missing on the API key') + @ApiAppErrorResponse(ERROR_CODE.SERVER_DISK_ERROR, 'An error occurred while writing to disk') + async uploadMedia( + @UserFile(['image/png', 'image/jpeg', 'image/webp', 'image/avif', 'image/tiff'], 8 * FileSize.MegaByte) + file: Promise, + @GetUser() user: User, + @Query() options: ImageMediaUploadReqDto, + ): Promise { + const multer = await file; + const media = await this.imageMediaService.convertMedia(multer, options); + const savedMedia = await this.imageMediaService.registerMedia(media, user, options.public ?? false); + try { + await this.imageMediaService.writeMediaToDisk(savedMedia.id, multer.multer.buffer); + } catch { + await this.imageMediaService.unRegisterMedia(savedMedia.id); + throw new AppException(ERROR_CODE.SERVER_DISK_ERROR); + } + this.imageMediaService.cleanup(); + return omit(savedMedia, 'uploaderId', 'uploadedAt'); + } +} diff --git a/src/media/image/imagemedia.module.ts b/src/media/image/imagemedia.module.ts new file mode 100644 index 00000000..a3978240 --- /dev/null +++ b/src/media/image/imagemedia.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ImageMediaController } from './imagemedia.controller'; +import { ImageMediaService } from './imagemedia.service'; + +@Module({ + controllers: [ImageMediaController], + providers: [ImageMediaService], + exports: [ImageMediaService], +}) +export class ImageMediaModule {} diff --git a/src/media/image/imagemedia.service.ts b/src/media/image/imagemedia.service.ts new file mode 100644 index 00000000..eeafca43 --- /dev/null +++ b/src/media/image/imagemedia.service.ts @@ -0,0 +1,121 @@ +import { createReadStream, ReadStream } from 'fs'; +import { rm, writeFile } from 'fs/promises'; +import { Injectable } from '@nestjs/common'; +import { RawImageMedia, ImageMediaPreset } from '../../prisma/types'; +import { ConfigModule } from '../../config/config.module'; +import { PrismaService } from '../../prisma/prisma.service'; +import { MulterWithMime } from '../../upload.interceptor'; +import { User } from '../../users/interfaces/user.interface'; +import ImageMediaUploadReqDto from './dto/req/imagemedia-upload-req.dto'; +import sharp from 'sharp'; + +export type ConversionOptions = Omit; + +type PresetStruct = Record< + Exclude, + Omit +>; +const presets: PresetStruct = { + AVATAR: { width: 256, height: 256, quality: 70, effort: 5 }, +}; + +export type ImageMetadata = Omit; + +@Injectable() +export class ImageMediaService { + constructor( + readonly prisma: PrismaService, + readonly config: ConfigModule, + ) {} + + async convertMedia(file: MulterWithMime, options: ConversionOptions): Promise { + if (!(options.preset in presets)) options.preset = ImageMediaPreset.CUSTOM; + if (options.preset) Object.assign(options, presets[options.preset]); + let instructions = sharp(file.multer.buffer); + let metadata = await instructions.metadata(); + const size = [metadata.width, metadata.height]; + if (options.rotation) { + instructions = instructions.rotate(options.rotation * 90); + size.reverse(); + } + if (size[0] > 1920 && !options.width) options.width = 1920; + if (size[1] > 1080 && !options.height) options.height = 1080; + if (options.width && options.height) + instructions = instructions.resize(options.width, options.height, { fit: 'cover' }); + file.mime = 'image/webp'; + instructions = instructions.webp({ + quality: options.quality, + effort: options.effort, + nearLossless: true, + smartSubsample: true, + alphaQuality: options.quality, + }); + file.multer.buffer = await instructions.toBuffer(); + metadata = await sharp(file.multer.buffer).metadata(); + return { width: metadata.width, height: metadata.height, size: file.multer.buffer.length, preset: options.preset }; + } + + async registerMedia(metaData: ImageMetadata, uploader: User, isPublic: boolean): Promise { + const image = await this.prisma.imageMedia.create({ + data: { + ...metaData, + uploader: { + connect: { id: uploader.id }, + }, + isPublic, + }, + }); + return image; + } + + async rollbackMedia(media: RawImageMedia): Promise { + await this.prisma.imageMedia.create({ data: media }); + } + + async unRegisterMedia(mediaId: string): Promise { + return this.prisma.imageMedia.delete({ where: { id: mediaId } }); + } + + async getMedia(mediaId: string) { + return this.prisma.imageMedia.findUnique({ where: { id: mediaId } }); + } + + /** + * Clears unused from the Database. {@link ImageMediaService.deleteMediaFromDisk DeleteMediaFromDisk} must be called + * with the output of this method to clear data from disk. + */ + async clearUnusedMedia(): Promise { + const targetMedias = await this.prisma.imageMedia.findMany({ + where: { + // Filter explanation https://www.prisma.io/docs/orm/prisma-client/queries/relation-queries#filter-on-absence-of--to-many-records + avatarForUsers: { none: {} }, + logoForAssos: { none: {} }, + descriptionForAssos: { none: {} }, + uploadedAt: { lt: new Date(Date.now() - this.config.MEDIA_DETACHED_LIFESPAN * 3_600_000) }, + }, + }); + await this.prisma.imageMedia.deleteMany({ + where: { id: { in: targetMedias.map((media) => media.id) } }, + }); + return targetMedias; + } + + async writeMediaToDisk(mediaId: string, buffer: Buffer): Promise { + await writeFile(`${this.config.MEDIA_UPLOAD_DIR}/image/${mediaId}.webp`, buffer); + } + + readMediaFromDisk(mediaId: string): ReadStream { + return createReadStream(`${this.config.MEDIA_UPLOAD_DIR}/image/${mediaId}.webp`); + } + + async deleteMediaFromDisk(mediaId: string): Promise { + await rm(`${this.config.MEDIA_UPLOAD_DIR}/image/${mediaId}.webp`, { force: true }); + } + + async cleanup() { + const media = await this.clearUnusedMedia(); + (await Promise.all(media.map((m) => this.deleteMediaFromDisk(m.id).catch(() => m)))).map( + (r) => r && this.rollbackMedia(r), + ); + } +} diff --git a/src/prisma/prisma.service.ts b/src/prisma/prisma.service.ts index 1f75e86f..23753f71 100644 --- a/src/prisma/prisma.service.ts +++ b/src/prisma/prisma.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { PrismaClient } from '@prisma/client'; +import { PrismaMariaDb } from '@prisma/adapter-mariadb'; +import { PrismaClient } from './types'; import { ConfigModule } from '../config/config.module'; import { generateCustomUserModel } from '../users/interfaces/user.interface'; import { omit } from '../utils'; @@ -18,6 +19,7 @@ import { generateCustomApplicationModel } from '../auth/application/interfaces/a @Injectable() export class PrismaService extends PrismaClient> { readonly normalize: ReturnType; + readonly adapter: Record<'adapter', PrismaMariaDb>; constructor(config: ConfigModule) { super(prismaOptions(config)); @@ -25,16 +27,10 @@ export class PrismaService extends PrismaClient } } -const prismaOptions = (config: ConfigModule) => ({ - datasources: { - db: { - url: config.DATABASE_URL, - }, - }, -}); +const prismaOptions = (config: ConfigModule) => ({ adapter: new PrismaMariaDb(config.DATABASE_URL) }); /** - * @typedef {import('@prisma/client').Prisma.UserDelegate} UserDelegate + * @typedef {import('../prisma/types').Prisma.UserDelegate} UserDelegate */ function createNormalizedEntitiesUtility(prisma: PrismaClient) { diff --git a/src/prisma/types.ts b/src/prisma/types.ts index c29ba04c..9dabfd11 100644 --- a/src/prisma/types.ts +++ b/src/prisma/types.ts @@ -1,6 +1,15 @@ -import { Language, Translation as RawTranslation } from '@prisma/client'; +import { Language, Translation as RawTranslation } from './types/client'; export { + Prisma, + PrismaClient, + UserType, + Sex, + AddressPrivacy, + Language, + Permission, + ImageMediaPreset, + TimetableEntryType, User as RawUser, UserInfos as RawUserInfos, TimetableEntry as RawTimetableEntry, @@ -37,7 +46,8 @@ export { UserPrivacy as RawUserPrivacy, ApiApplication as RawApiApplication, ApiKey as RawApiKey, -} from '@prisma/client'; + ImageMedia as RawImageMedia, +} from './types/client'; export { RawTranslation }; export type Translation = Pick, Language>; diff --git a/src/ue/annals/annals.controller.ts b/src/ue/annals/annals.controller.ts index 67a47720..47d7efb7 100644 --- a/src/ue/annals/annals.controller.ts +++ b/src/ue/annals/annals.controller.ts @@ -17,7 +17,7 @@ import { ApiAppErrorResponse } from '../../app.dto'; import UeAnnalResDto from './dto/res/ue-annal-res.dto'; import UeAnnalMetadataResDto from './dto/res/ue-annal-metadata-res.dto'; import { GetPermissions } from '../../auth/decorator/get-permissions.decorator'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../prisma/types'; import { omit, PermissionManager } from '../../utils'; @Controller('ue/annals') diff --git a/src/ue/annals/annals.service.ts b/src/ue/annals/annals.service.ts index b68f2a0b..3991f850 100644 --- a/src/ue/annals/annals.service.ts +++ b/src/ue/annals/annals.service.ts @@ -9,7 +9,7 @@ import { CreateAnnalReqDto } from './dto/req/create-annal-req.dto'; import { UpdateAnnalReqDto } from './dto/req/update-annal-req.dto'; import { ConfigModule } from '../../config/config.module'; import { User } from '../../users/interfaces/user.interface'; -import { Semester } from '@prisma/client'; +import { RawSemester } from '../../prisma/types'; @Injectable() export class AnnalsService { @@ -39,7 +39,7 @@ export class AnnalsService { }, }) ).map((subscription) => subscription.semesterId) - : [...ueof.reduce((prev, nxt) => new Set([...prev, ...nxt.openSemester]), new Set())].map( + : [...ueof.reduce((prev, nxt) => new Set([...prev, ...nxt.openSemester]), new Set())].map( (semester) => semester.code, ); const annalType = await this.prisma.ueAnnalType.findMany(); diff --git a/src/ue/annals/interfaces/annal.interface.ts b/src/ue/annals/interfaces/annal.interface.ts index ac00e9d4..672ced47 100644 --- a/src/ue/annals/interfaces/annal.interface.ts +++ b/src/ue/annals/interfaces/annal.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../../prisma/types'; import { omit } from '../../../utils'; import { CommentStatus } from '../../comments/interfaces/comment.interface'; import { generateCustomModel } from '../../../prisma/prisma.service'; diff --git a/src/ue/comments/comments.controller.ts b/src/ue/comments/comments.controller.ts index 1b5c86cb..2ea8d86f 100644 --- a/src/ue/comments/comments.controller.ts +++ b/src/ue/comments/comments.controller.ts @@ -14,7 +14,7 @@ import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; import { ApiAppErrorResponse, paginatedResponseDto } from '../../app.dto'; import { UeCommentUpvoteResDto$False, UeCommentUpvoteResDto$True } from './dto/res/ue-comment-upvote-res.dto'; import UeCommentReplyResDto from './dto/res/ue-comment-reply-res.dto'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../prisma/types'; import { GetPermissions } from '../../auth/decorator/get-permissions.decorator'; import { PermissionManager } from '../../utils'; diff --git a/src/ue/comments/interfaces/comment-reply.interface.ts b/src/ue/comments/interfaces/comment-reply.interface.ts index b2e53ce7..c083e595 100644 --- a/src/ue/comments/interfaces/comment-reply.interface.ts +++ b/src/ue/comments/interfaces/comment-reply.interface.ts @@ -1,5 +1,5 @@ import { CommentStatus } from './comment.interface'; -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../../prisma/types'; import { omit } from '../../../utils'; import { generateCustomModel } from '../../../prisma/prisma.service'; diff --git a/src/ue/comments/interfaces/comment.interface.ts b/src/ue/comments/interfaces/comment.interface.ts index 0b0ef655..3b8e58c9 100644 --- a/src/ue/comments/interfaces/comment.interface.ts +++ b/src/ue/comments/interfaces/comment.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../../prisma/types'; import { RequestType, generateCustomModel } from '../../../prisma/prisma.service'; import { UeCommentReply, formatReply } from './comment-reply.interface'; import { omit } from '../../../utils'; diff --git a/src/ue/credit/interfaces/credit-category.interface.ts b/src/ue/credit/interfaces/credit-category.interface.ts index 3674aa10..fed23082 100644 --- a/src/ue/credit/interfaces/credit-category.interface.ts +++ b/src/ue/credit/interfaces/credit-category.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../../prisma/types'; import { RequestType, generateCustomModel } from '../../../prisma/prisma.service'; const CREDIT_CATEGORY_SELECT_FILTER = { diff --git a/src/ue/interfaces/criterion.interface.ts b/src/ue/interfaces/criterion.interface.ts index 7b7a80a7..2d546abf 100644 --- a/src/ue/interfaces/criterion.interface.ts +++ b/src/ue/interfaces/criterion.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../prisma/types'; import { generateCustomModel } from '../../prisma/prisma.service'; const CRITERION_SELECT_FILTER = { diff --git a/src/ue/interfaces/rate.interface.ts b/src/ue/interfaces/rate.interface.ts index 9db0f341..0b17922c 100644 --- a/src/ue/interfaces/rate.interface.ts +++ b/src/ue/interfaces/rate.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../prisma/types'; import { generateCustomModel } from '../../prisma/prisma.service'; const RATE_SELECT_FILTER = { diff --git a/src/ue/interfaces/ue.interface.ts b/src/ue/interfaces/ue.interface.ts index 6c8e50ba..3e6f3076 100644 --- a/src/ue/interfaces/ue.interface.ts +++ b/src/ue/interfaces/ue.interface.ts @@ -1,4 +1,4 @@ -import { Prisma, PrismaClient } from '@prisma/client'; +import { Prisma, PrismaClient } from '../../prisma/types'; import { generateCustomModel } from '../../prisma/prisma.service'; import { omit, translationSelect } from '../../utils'; diff --git a/src/ue/ue.controller.ts b/src/ue/ue.controller.ts index b6426ce6..42384666 100644 --- a/src/ue/ue.controller.ts +++ b/src/ue/ue.controller.ts @@ -15,7 +15,7 @@ import { UeDetailResDto } from './dto/res/ue-detail-res.dto'; import { UeOverviewResDto } from './dto/res/ue-overview-res.dto'; import UeRateCriterionResDto from './dto/res/ue-rate-criterion-res.dto'; import UeRateResDto from './dto/res/ue-rate-res.dto'; -import { Language, UserType } from '@prisma/client'; +import { Language, UserType } from '../prisma/types'; import { UeRating } from './interfaces/rate.interface'; @Controller('ue') diff --git a/src/ue/ue.service.ts b/src/ue/ue.service.ts index 29e6ff4e..10e93f8b 100644 --- a/src/ue/ue.service.ts +++ b/src/ue/ue.service.ts @@ -6,7 +6,7 @@ import { Ue } from './interfaces/ue.interface'; import { Criterion } from './interfaces/criterion.interface'; import { UeRating } from './interfaces/rate.interface'; import { ConfigModule } from '../config/config.module'; -import { Language, Prisma } from '@prisma/client'; +import { Language, Prisma } from '../prisma/types'; import { SemesterService } from '../semester/semester.service'; @Injectable() diff --git a/src/users/dto/req/users-update-req.dto.ts b/src/users/dto/req/users-update-req.dto.ts index bfb06635..85d0f2d4 100644 --- a/src/users/dto/req/users-update-req.dto.ts +++ b/src/users/dto/req/users-update-req.dto.ts @@ -1,4 +1,4 @@ -import { AddressPrivacy, Language } from '@prisma/client'; +import { AddressPrivacy, Language } from '../../../prisma/types'; import { IsArray, IsBoolean, IsEnum, IsOptional, IsString } from 'class-validator'; export class UserUpdateReqDto { diff --git a/src/users/dto/res/user-detail-res.dto.ts b/src/users/dto/res/user-detail-res.dto.ts index f9ab971d..c99a7a14 100644 --- a/src/users/dto/res/user-detail-res.dto.ts +++ b/src/users/dto/res/user-detail-res.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { AddressPrivacy, Sex, UserType } from '@prisma/client'; +import { AddressPrivacy, Sex, UserType } from '../../../prisma/types'; export default class UserDetailResDto { id: string; diff --git a/src/users/dto/res/user-overview-res.dto.ts b/src/users/dto/res/user-overview-res.dto.ts index 582228b5..74e5a965 100644 --- a/src/users/dto/res/user-overview-res.dto.ts +++ b/src/users/dto/res/user-overview-res.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { Sex, UserType } from '@prisma/client'; +import { Sex, UserType } from '../../../prisma/types'; export default class UserOverviewResDto { id: string; diff --git a/src/users/interfaces/user.interface.ts b/src/users/interfaces/user.interface.ts index fedd7b3b..dc6c65f7 100644 --- a/src/users/interfaces/user.interface.ts +++ b/src/users/interfaces/user.interface.ts @@ -1,6 +1,5 @@ -import { Prisma, PrismaClient } from '@prisma/client'; import { generateCustomModel, RequestType } from '../../prisma/prisma.service'; -import { Translation } from '../../prisma/types'; +import { Prisma, PrismaClient, Translation } from '../../prisma/types'; const USER_SELECT_FILTER = { select: { diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 28062760..ca890110 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -112,7 +112,8 @@ export default class UsersController { studentId: user.studentId, userType: user.userType, infos: { - ...pick(user.infos, 'nickname', 'avatar', 'nationality', 'passions', 'website'), + ...pick(user.infos, 'nickname', 'nationality', 'passions', 'website'), + avatar: user.infos.avatar ? `/media/image/${user.infos.avatar.id}.webp` : null, sex: user.privacy.sex || includeAll ? user.infos.sex : undefined, birthday: user.privacy.birthday || includeAll ? user.infos.birthday : undefined, }, @@ -153,7 +154,7 @@ export default class UsersController { lastName: user.lastName, nickname: user.infos.nickname, type: user.userType, - avatar: user.infos.avatar, + avatar: user.infos.avatar ? `/media/image/${user.infos.avatar.id}.webp` : null, sex: user.privacy.sex || includeAll ? user.infos.sex : undefined, nationality: user.infos.nationality, birthday: user.privacy.birthday || includeAll ? user.infos.birthday : undefined, diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 8c039e40..78d4884f 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -5,7 +5,7 @@ import UsersSearchReqDto from './dto/req/users-search-req.dto'; import { UserUpdateReqDto } from './dto/req/users-update-req.dto'; import { omit, translationSelect } from '../utils'; import { ConfigModule } from '../config/config.module'; -import { Prisma } from '@prisma/client'; +import { Prisma } from '../prisma/types'; @Injectable() export default class UsersService { @@ -124,7 +124,14 @@ export default class UsersService { }, }, }) - ).map((membership) => ({ ...omit(membership, 'role'), role: membership.role.name })); + ).map((membership) => ({ + ...omit(membership, 'role'), + role: membership.role.name, + asso: { + ...membership.asso, + logo: membership.asso.logo ? `/media/image/${membership.asso.logo.id}.webp` : null, + }, + })); return membership; } @@ -135,7 +142,7 @@ export default class UsersService { infos: { update: { nickname: dto.nickname, - avatar: dto.avatar, + avatar: { connect: dto.avatar ? { id: dto.avatar } : undefined }, passions: dto.passions, website: dto.website, }, diff --git a/src/utils.ts b/src/utils.ts index 8e468be3..80ded01f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,5 @@ -import { Language, Permission } from '@prisma/client'; +import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { Language, Permission } from './prisma/types'; import { Translation } from './prisma/types'; import { ApiPermission, UserPermission } from './auth/interfaces/permissions.interface'; @@ -57,6 +58,29 @@ export const translationSelect = { }, }; +export class TranslatedTextDto { + @IsOptional() + @IsString() + @IsNotEmpty() + fr?: string; + @IsOptional() + @IsString() + @IsNotEmpty() + en?: string; + @IsOptional() + @IsString() + @IsNotEmpty() + de?: string; + @IsOptional() + @IsString() + @IsNotEmpty() + es?: string; + @IsOptional() + @IsString() + @IsNotEmpty() + zh?: string; +} + export class PermissionManager { public readonly hardPermissions: Permission[]; public readonly softPermissions: { diff --git a/test/declarations.d.ts b/test/declarations.d.ts index bf412f0a..bb778dc2 100644 --- a/test/declarations.d.ts +++ b/test/declarations.d.ts @@ -7,6 +7,7 @@ import { FakeAssoMembership, FakeAssoMembershipPermission, FakeAssoMembershipRole, + FakeImageMedia, FakeUeAnnalType, FakeUeof, } from './utils/fakedb'; @@ -15,15 +16,17 @@ import { Criterion } from 'src/ue/interfaces/criterion.interface'; import { UeRating } from 'src/ue/interfaces/rate.interface'; import { FakeUe, FakeUser, FakeHomepageWidget, FakeAsso } from './utils/fakedb'; import { AppProvider } from './utils/test_utils'; -import { Language } from '@prisma/client'; +import { Language } from '../src/prisma/types'; import { PermissionManager } from '../src/utils'; type JsonLikeVariant = Partial<{ [K in keyof T]: T[K] extends string | Date ? symbol | RegExp | T[K] - : T[K] extends (infer R)[] - ? JsonLikeVariant[] - : JsonLikeVariant; + : T[K] extends number + ? symbol | number + : T[K] extends (infer R)[] + ? JsonLikeVariant[] + : JsonLikeVariant; }>; type FakeUeWithOfs = FakeUe & { ueofs: FakeUeof[] }; @@ -104,6 +107,7 @@ declare module './declarations' { expectCreditCategories(categories: JsonLikeVariant): this; expectApplications(applications: FakeApiApplication[]): this; expectApplication(application: FakeApiApplication): this; + expectImageMedia(media: JsonLikeVariant): this; expectPermissions(permissions: PermissionManager): this; diff --git a/test/declarations.ts b/test/declarations.ts index 1d8e1f5f..536f626e 100644 --- a/test/declarations.ts +++ b/test/declarations.ts @@ -15,13 +15,14 @@ import { FakeApiApplication, FakeAssoMembershipRole, FakeAssoMembership, + FakeImageMedia, } from './utils/fakedb'; import { UeAnnalFile } from 'src/ue/annals/interfaces/annal.interface'; import { ConfigModule } from '../src/config/config.module'; import { AppProvider, JsonLike } from './utils/test_utils'; import { getTranslation, omit, PermissionManager, pick } from '../src/utils'; -import { regex, string, uuid } from 'pactum-matchers'; -import { Language } from '@prisma/client'; +import { regex, string, uuid, int } from 'pactum-matchers'; +import { Language } from '../src/prisma/types'; import { DEFAULT_APPLICATION } from '../prisma/seed/utils'; import ApplicationResDto from '../src/auth/application/dto/res/application-res.dto'; import PermissionsResDto from '../src/auth/permissions/dto/res/permissions.dto'; @@ -133,7 +134,10 @@ Spec.prototype.expectUsers = function (app: AppProvider, users: FakeUser[], coun return (this).expectStatus(HttpStatus.OK).$expectRegexableJson({ items: users.map((user) => ({ ...pick(user, 'id', 'firstName', 'lastName', 'login', 'studentId', 'userType'), - infos: pick(user.infos, 'nickname', 'avatar', 'nationality', 'passions', 'website'), + infos: { + ...pick(user.infos, 'nickname', 'nationality', 'passions', 'website'), + avatar: user.infos.avatarMediaId ? `/media/image/${user.infos.avatarMediaId}.webp` : null, + }, branchSubscriptions: user.branchSubscriptions.map((branch) => pick(branch, 'id')), mailsPhones: pick(user.mailsPhones, 'mailUTT'), socialNetwork: omit(user.socialNetwork, 'id', 'discord'), @@ -223,7 +227,8 @@ Spec.prototype.expectHomepageWidgets = function (this: Spec, widgets: Omit ({ - ...pick(asso, 'id', 'name', 'logo'), + ...pick(asso, 'id', 'name'), + logo: asso.logoMediaId ? `/media/image/${asso.logoMediaId}.webp` : null, shortDescription: getTranslation(asso.descriptionShortTranslation, (this).language), president: { role: !!asso.presidentRole ? pick(asso.presidentRole, 'id', 'name') : null, @@ -236,7 +241,8 @@ Spec.prototype.expectAssos = function (this: Spec, app: AppProvider, assos: Fake }; Spec.prototype.expectAsso = function (asso: FakeAsso) { return (this).expectStatus(HttpStatus.OK).expectJson({ - ...pick(asso, 'id', 'name', 'mail', 'phoneNumber', 'website', 'logo'), + ...pick(asso, 'id', 'name', 'mail', 'phoneNumber', 'website'), + logo: asso.logoMediaId ? `/media/image/${asso.logoMediaId}.webp` : null, description: getTranslation(asso.descriptionTranslation, (this).language), president: { role: !!asso.presidentRole ? pick(asso.presidentRole, 'id', 'name') : null, @@ -315,6 +321,16 @@ Spec.prototype.expectPermissions = function (permissions: PermissionManager) { .mappedSort((permission) => permission.permission), } satisfies PermissionsResDto); }; +Spec.prototype.expectImageMedia = function (media: JsonLikeVariant) { + return (this).expectStatus(HttpStatus.CREATED).$expectRegexableJson({ + id: media.id, + size: media.size, + width: media.width, + height: media.height, + preset: media.preset, + isPublic: media.isPublic, + }); +}; export { Spec, JsonLikeVariant, FakeUeWithOfs }; @@ -330,6 +346,8 @@ Spec.prototype.$expectRegexableJson = function (this: Spec, obj: JsonLikeVari return string(); case JsonLike.UUID: return uuid(); + case JsonLike.INT: + return int(); } } if (Array.isArray(obj)) return obj.map(wrap); @@ -362,6 +380,7 @@ function generateSchema(obj: JsonLikeVariant): object { ), }; if (obj === JsonLike.STRING || obj === JsonLike.UUID) return { type: 'string' }; + if (obj === JsonLike.INT) return { type: 'number' }; switch (typeof obj) { case 'string': return { type: 'string' }; diff --git a/test/e2e/app.e2e-spec.ts b/test/e2e/app.e2e-spec.ts index 4a16e08f..ffb1a38d 100644 --- a/test/e2e/app.e2e-spec.ts +++ b/test/e2e/app.e2e-spec.ts @@ -15,6 +15,7 @@ import * as cas from '../external_services/cas'; import * as timetableProvider from '../external_services/timetable'; import { ConfigModule } from '../../src/config/config.module'; import AssoE2ESpec from './assos'; +import MediaE2ESpec from './media'; describe('EtuUTT API e2e testing', () => { let app: INestApplication; @@ -54,4 +55,5 @@ describe('EtuUTT API e2e testing', () => { TimetableE2ESpec(() => app); // Deactivated, see function UeE2ESpec(() => app); AssoE2ESpec(() => app); + MediaE2ESpec(() => app); }); diff --git a/test/e2e/assos/index.ts b/test/e2e/assos/index.ts index 5ce31380..4948959c 100644 --- a/test/e2e/assos/index.ts +++ b/test/e2e/assos/index.ts @@ -1,6 +1,7 @@ import { INestApplication } from '@nestjs/common'; import SearchE2ESpec from './search.e2e-spec'; import GetAssoE2ESpec from './get-asso.e2e-spec'; +import UpdateAssoE2ESpec from './update-asso.e2e-spec'; import GetAssoMembersE2ESpec from './list-members.e2e-spec'; import AddAssoMemberE2ESpec from './add-member.e2e-spec'; import KickAssoMemberE2ESpec from './kick-member.e2e-spec'; @@ -13,6 +14,7 @@ export default function AssoE2ESpec(app: () => INestApplication) { describe('Assos', () => { SearchE2ESpec(app); GetAssoE2ESpec(app); + UpdateAssoE2ESpec(app); GetAssoMembersE2ESpec(app); AddAssoMemberE2ESpec(app); KickAssoMemberE2ESpec(app); diff --git a/test/e2e/assos/update-asso.e2e-spec.ts b/test/e2e/assos/update-asso.e2e-spec.ts new file mode 100644 index 00000000..1ac05b3a --- /dev/null +++ b/test/e2e/assos/update-asso.e2e-spec.ts @@ -0,0 +1,170 @@ +import { Dummies, e2eSuite } from '../../utils/test_utils'; +import { + createAsso, + createAssoMembership, + createAssoMembershipPermission, + createAssoMembershipRole, + createImageMedia, + createUser, +} from '../../utils/fakedb'; +import * as pactum from 'pactum'; +import { ERROR_CODE } from '../../../src/exceptions'; +import { PrismaService } from '../../../src/prisma/prisma.service'; +import { pick } from '../../../src/utils'; + +const UpdateAssoE2ESpec = e2eSuite('PATCH /assos/:id', (app) => { + const userNotAllowed = createUser(app); + const userAllowed = createUser(app); + const asso = createAsso(app); + const assoMembershipRoleInAsso = createAssoMembershipRole(app, { asso }); + const manageInfosPermission = createAssoMembershipPermission(app, { id: 'manage_infos' }); + createAssoMembership(app, { + asso, + role: assoMembershipRoleInAsso, + user: userAllowed, + permissions: [manageInfosPermission], + }); + const nonPublicMedia = createImageMedia(app, { isPublic: false, preset: 'AVATAR' }); + const nonAvatarMedia = createImageMedia(app, { isPublic: true, preset: 'CUSTOM' }); + const publicMedia = createImageMedia(app, { isPublic: true, preset: 'AVATAR' }); + + const lexicalText = `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"I want you as a ","type":"color-text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"lexical","type":"color-text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" text that passes the ","type":"color-text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"tests","type":"color-text","version":1,"color":"blue"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"color-text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`; + const nonLexicalText = 'I want you as a non-lexical text that does not pass the tests.'; + const validBody = { + name: 'New name', + email: 'test@utt.fr', + phoneNumber: '+33325000000', + website: 'https://www.utt.fr', + description: { fr: lexicalText }, + descriptionShort: { fr: 'some description' }, + }; + + it('should return 403 as user is not authenticated', () => + pactum.spec().patch(`/assos/${asso.id}`).withBody(validBody).expectAppError(ERROR_CODE.NOT_LOGGED_IN)); + + it('should return a 400 as the asso id param is not valid', () => + pactum + .spec() + .withBearerToken(userNotAllowed.token) + .patch(`/assos/thisisnotavaliduuid`) + .withBody(validBody) + .expectAppError(ERROR_CODE.PARAM_NOT_UUID, 'assoId')); + + it('should return a 404 as asso is not found', () => + pactum + .spec() + .withBearerToken(userNotAllowed.token) + .patch(`/assos/${Dummies.UUID}`) + .withBody(validBody) + .expectAppError(ERROR_CODE.NO_SUCH_ASSO, Dummies.UUID)); + + it('should return a 403 as user has no permission', () => + pactum + .spec() + .withBearerToken(userNotAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody(validBody) + .expectAppError(ERROR_CODE.FORBIDDEN_ASSOS_PERMISSIONS, asso.id, manageInfosPermission.id)); + + it('should return a 401 as description is non lexical', () => + pactum + .spec() + .withBearerToken(userAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody({ ...validBody, description: { fr: nonLexicalText } }) + .expectAppError(ERROR_CODE.PARAM_LEXICAL_ILLEGAL, 'description.fr')); + + it('should return a 404 as media does not exist', () => + pactum + .spec() + .withBearerToken(userAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody({ ...validBody, logo: Dummies.UUID }) + .expectAppError(ERROR_CODE.NO_SUCH_MEDIA, Dummies.UUID)); + + it('should return a 404 as media is not public', () => + pactum + .spec() + .withBearerToken(userAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody({ ...validBody, logo: nonPublicMedia.id }) + .expectAppError(ERROR_CODE.MEDIA_NOT_PUBLIC)); + + it('should return a 404 as media is not public', () => + pactum + .spec() + .withBearerToken(userAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody({ ...validBody, logo: nonAvatarMedia.id }) + .expectAppError(ERROR_CODE.MEDIA_PRESET_REQUIRED, 'AVATAR')); + + it('should return a 404 as media is not public', () => + pactum + .spec() + .withBearerToken(userAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody({ ...validBody, logo: nonAvatarMedia.id }) + .expectAppError(ERROR_CODE.MEDIA_PRESET_REQUIRED, 'AVATAR')); + + it('should update the asso', async () => { + await pactum + .spec() + .withBearerToken(userAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody({ ...validBody, logo: publicMedia.id }) + .expectAsso({ + ...asso, + ...pick(validBody, 'name', 'phoneNumber', 'website'), + descriptionShortTranslation: validBody.descriptionShort, + descriptionTranslation: validBody.description, + mail: validBody.email, + logoMediaId: publicMedia.id, + }); + await app() + .get(PrismaService) + .asso.update({ + where: { id: asso.id }, + data: { + ...pick(asso, 'name', 'mail', 'phoneNumber', 'website'), + logo: { disconnect: true }, + descriptionTranslation: { update: validBody.description }, + descriptionShortTranslation: { update: validBody.descriptionShort }, + }, + }); + }); + + it('should update the asso and link media to description and ignore invalid media', async () => { + const lexicalTextWithImage = `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"I want you as a ","type":"color-text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"lexical","type":"color-text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" text that passes the ","type":"color-text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":"tests","type":"color-text","version":1,"color":"blue"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"color-text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"type":"image","version":1,"src":"https://etu.utt.fr/api/v1/media/image/${publicMedia.id}.webp","altText":"","width":1920,"height":1080}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"type":"image","version":1,"src":"https://etu.utt.fr/api/v1/media/image/${Dummies.UUID}.webp","altText":"","width":1920,"height":1080}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`; + await pactum + .spec() + .withBearerToken(userAllowed.token) + .patch(`/assos/${asso.id}`) + .withBody({ ...validBody, description: { fr: lexicalTextWithImage }, logo: publicMedia.id }) + .expectAsso({ + ...asso, + ...pick(validBody, 'name', 'phoneNumber', 'website'), + descriptionShortTranslation: validBody.descriptionShort, + descriptionTranslation: { fr: lexicalTextWithImage }, + mail: validBody.email, + logoMediaId: publicMedia.id, + }); + const { descriptionImages } = await app() + .get(PrismaService) + .asso.findUnique({ where: { id: asso.id }, include: { descriptionImages: true } }); + expect(descriptionImages.length).toBe(1); + return app() + .get(PrismaService) + .asso.update({ + where: { id: asso.id }, + data: { + ...pick(asso, 'name', 'mail', 'phoneNumber', 'website'), + logo: { disconnect: true }, + descriptionImages: { disconnect: { id: publicMedia.id } }, + descriptionTranslation: { update: validBody.description }, + descriptionShortTranslation: { update: validBody.descriptionShort }, + }, + }); + }); +}); + +export default UpdateAssoE2ESpec; diff --git a/test/e2e/auth/application/get-applications-of-user.e2e-spec.ts b/test/e2e/auth/application/get-applications-of-user.e2e-spec.ts index a75dfa7b..280e9da5 100644 --- a/test/e2e/auth/application/get-applications-of-user.e2e-spec.ts +++ b/test/e2e/auth/application/get-applications-of-user.e2e-spec.ts @@ -2,7 +2,7 @@ import { e2eSuite } from '../../../utils/test_utils'; import * as pactum from 'pactum'; import { ERROR_CODE } from '../../../../src/exceptions'; import * as fakedb from '../../../utils/fakedb'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../../../src/prisma/types'; import { PermissionManager } from '../../../../src/utils'; const GetApplicationsOfUserE2ESpec = e2eSuite('GET /auth/application/of/:userId', (app) => { diff --git a/test/e2e/auth/cas-sign-up.e2e-spec.ts b/test/e2e/auth/cas-sign-up.e2e-spec.ts index ec6c34c0..08878111 100644 --- a/test/e2e/auth/cas-sign-up.e2e-spec.ts +++ b/test/e2e/auth/cas-sign-up.e2e-spec.ts @@ -21,7 +21,7 @@ const CasSignUpE2ESpec = e2eSuite('POST /auth/signup/cas', (app) => { end: new Date(), }); const ue = fakedb.createUe(app); - fakedb.createUeof(app, { branchOptions: [branchOption], semesters: [semester], ue }); + const ueof = fakedb.createUeof(app, { branchOptions: [branchOption], semesters: [semester], ue }); mockLdapServer(list); @@ -81,7 +81,7 @@ const CasSignUpE2ESpec = e2eSuite('POST /auth/signup/cas', (app) => { datefin: 20240930, jpegPhoto: `http://localhost/${login}.jpg`, gidNumber: type === 'student' ? '10000' : type === 'faculty' ? '5000' : '9999', - uv: ['PETM6', 'SY16', 'LO17', 'RE02', 'IF03', 'CTC1', 'LG11', 'PEICT', ue.code], + uv: [ueof.code], }; }; const executeValidSignupRequest = async (personAttributes) => { diff --git a/test/e2e/auth/permissions/get-own-permissions.ts b/test/e2e/auth/permissions/get-own-permissions.ts index 6f5988c8..668fa185 100644 --- a/test/e2e/auth/permissions/get-own-permissions.ts +++ b/test/e2e/auth/permissions/get-own-permissions.ts @@ -2,7 +2,7 @@ import { e2eSuite } from '../../../utils/test_utils'; import * as pactum from 'pactum'; import * as fakedb from '../../../utils/fakedb'; import { ERROR_CODE } from '../../../../src/exceptions'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../../../src/prisma/types'; import { PermissionManager } from '../../../../src/utils'; const GetOwnPermissionsE2ESpec = e2eSuite('GET /auth/permissions/current', (app) => { diff --git a/test/e2e/auth/permissions/get-permissions.e2e-spec.ts b/test/e2e/auth/permissions/get-permissions.e2e-spec.ts index a190b3d6..deba64af 100644 --- a/test/e2e/auth/permissions/get-permissions.e2e-spec.ts +++ b/test/e2e/auth/permissions/get-permissions.e2e-spec.ts @@ -2,7 +2,7 @@ import { e2eSuite } from '../../../utils/test_utils'; import * as pactum from 'pactum'; import * as fakedb from '../../../utils/fakedb'; import { ERROR_CODE } from '../../../../src/exceptions'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../../../src/prisma/types'; import { PermissionManager } from '../../../../src/utils'; const GetPermissionsE2ESpec = e2eSuite('GET /auth/permissions/:apiKey', (app) => { diff --git a/test/e2e/auth/signup-e2e-spec.ts b/test/e2e/auth/signup-e2e-spec.ts index 4008804a..3c55ea04 100644 --- a/test/e2e/auth/signup-e2e-spec.ts +++ b/test/e2e/auth/signup-e2e-spec.ts @@ -3,7 +3,7 @@ import * as pactum from 'pactum'; import { PrismaService } from '../../../src/prisma/prisma.service'; import { e2eSuite } from '../../utils/test_utils'; import { ERROR_CODE } from '../../../src/exceptions'; -import { UserType } from '@prisma/client'; +import { UserType } from '../../../src/prisma/types'; import { createUser } from '../../utils/fakedb'; import { JwtService } from '@nestjs/jwt'; @@ -86,11 +86,7 @@ const SignupE2ESpec = e2eSuite('POST /auth/signup', (app) => { .expectAppError(ERROR_CODE.PARAM_NOT_DATE, 'birthday'); }); it('should return a 400 if no body is provided', async () => { - return pactum - .spec() - .post('/auth/signup') - .withBody(undefined) - .expectAppError(ERROR_CODE.BODY_MISSING); + return pactum.spec().post('/auth/signup').withBody(undefined).expectAppError(ERROR_CODE.BODY_MISSING); }); it('should create a new user', async () => { await pactum diff --git a/test/e2e/media/image/artifacts/image.avif b/test/e2e/media/image/artifacts/image.avif new file mode 100644 index 00000000..3277d9cb Binary files /dev/null and b/test/e2e/media/image/artifacts/image.avif differ diff --git a/test/e2e/media/image/artifacts/image.gif b/test/e2e/media/image/artifacts/image.gif new file mode 100644 index 00000000..0857f028 Binary files /dev/null and b/test/e2e/media/image/artifacts/image.gif differ diff --git a/test/e2e/media/image/artifacts/image.gif.png b/test/e2e/media/image/artifacts/image.gif.png new file mode 100644 index 00000000..0857f028 Binary files /dev/null and b/test/e2e/media/image/artifacts/image.gif.png differ diff --git a/test/e2e/media/image/artifacts/image.jpg b/test/e2e/media/image/artifacts/image.jpg new file mode 100644 index 00000000..e5cc26cf Binary files /dev/null and b/test/e2e/media/image/artifacts/image.jpg differ diff --git a/test/e2e/media/image/artifacts/image.png b/test/e2e/media/image/artifacts/image.png new file mode 100644 index 00000000..96fa3533 Binary files /dev/null and b/test/e2e/media/image/artifacts/image.png differ diff --git a/test/e2e/media/image/artifacts/image.tif b/test/e2e/media/image/artifacts/image.tif new file mode 100644 index 00000000..d54802d4 Binary files /dev/null and b/test/e2e/media/image/artifacts/image.tif differ diff --git a/test/e2e/media/image/artifacts/image.webp b/test/e2e/media/image/artifacts/image.webp new file mode 100644 index 00000000..c7239776 Binary files /dev/null and b/test/e2e/media/image/artifacts/image.webp differ diff --git a/test/e2e/media/image/get-media.e2e-spec.ts b/test/e2e/media/image/get-media.e2e-spec.ts new file mode 100644 index 00000000..09ed3732 --- /dev/null +++ b/test/e2e/media/image/get-media.e2e-spec.ts @@ -0,0 +1,56 @@ +import { Dummies, e2eSuite } from '../../../utils/test_utils'; +import * as fakedb from '../../../utils/fakedb'; +import { cpSync, mkdirSync, rmSync } from 'fs'; +import { ConfigModule } from '../../../../src/config/config.module'; +import { createUser } from '../../../utils/fakedb'; +import { ERROR_CODE } from '../../../../src/exceptions'; +import * as pactum from 'pactum'; + +export const GetMediaE2ESpec = e2eSuite('GET /media/image/:mediaId', (app) => { + const user = createUser(app); + const publicMedia = fakedb.createImageMedia(app, { isPublic: true }); + const nonPublicMedia = fakedb.createImageMedia(app, { isPublic: false }); + const publicMediaInError = fakedb.createImageMedia(app, { isPublic: true }); + + beforeAll(() => { + mkdirSync(`${app().get(ConfigModule).MEDIA_UPLOAD_DIR}/image`, { recursive: true }); + cpSync( + `test/e2e/media/image/artifacts/image.webp`, + `${app().get(ConfigModule).MEDIA_UPLOAD_DIR}/image/${publicMedia.id}.webp`, + ); + cpSync( + `test/e2e/media/image/artifacts/image.webp`, + `${app().get(ConfigModule).MEDIA_UPLOAD_DIR}/image/${nonPublicMedia.id}.webp`, + ); + }); + + afterAll(() => { + rmSync(app().get(ConfigModule).MEDIA_UPLOAD_DIR.split('/')[0], { recursive: true }); + }); + + it('should return a 404 as the media does not exist', () => + pactum.spec().get(`/media/image/${Dummies.UUID}.webp`).expectAppError(ERROR_CODE.NO_SUCH_MEDIA, Dummies.UUID)); + + it('should return a 401 as the media is not public', () => + pactum.spec().get(`/media/image/${nonPublicMedia.id}.webp`).expectAppError(ERROR_CODE.NOT_LOGGED_IN)); + + it('should return a 200 and the media (public)', () => + pactum + .spec() + .get(`/media/image/${publicMedia.id}.webp`) + .expectStatus(200) + .expectHeader('content-type', 'image/webp') + .expectBodyContains('RIFF')); + + it('should return a 200 and the media (not public)', () => + pactum + .spec() + .withBearerToken(user.token) + .get(`/media/image/${nonPublicMedia.id}.webp`) + .expectStatus(200) + .expectHeader('content-type', 'image/webp') + .expectBodyContains('RIFF')); + + it('should return a 503 as there is an error reading the file', () => + pactum.spec().get(`/media/image/${publicMediaInError.id}.webp`).expectAppError(ERROR_CODE.SERVER_DISK_ERROR)); +}); diff --git a/test/e2e/media/image/upload-media.e2e-spec.ts b/test/e2e/media/image/upload-media.e2e-spec.ts new file mode 100644 index 00000000..a36452d8 --- /dev/null +++ b/test/e2e/media/image/upload-media.e2e-spec.ts @@ -0,0 +1,142 @@ +import { ImageMediaPreset } from '../../../../src/prisma/types'; +import { mkdirSync, rmSync } from 'fs'; +import { ERROR_CODE } from '../../../../src/exceptions'; +import { createUser } from '../../../utils/fakedb'; +import { e2eSuite, JsonLike } from '../../../utils/test_utils'; +import { ConfigModule } from '../../../../src/config/config.module'; +import { PermissionManager } from '../../../../src/utils'; +import * as pactum from 'pactum'; + +export const UploadMediaE2ESpec = e2eSuite('POST /media/image', (app) => { + const user = createUser(app, { permissions: new PermissionManager().with('API_UPLOAD_MEDIA') }); + const unauthorizedUser = createUser(app); + + const params = { + public: true, + preset: ImageMediaPreset.AVATAR, + rotation: 1, + effort: 2, + quality: 100, + width: 150, + height: 150, + }; + + it('should return a 401 as user is not authenticated', () => { + return pactum.spec().post(`/media/image`).expectAppError(ERROR_CODE.NOT_LOGGED_IN); + }); + + it('should fail as the user does not have the required permissions', () => + pactum + .spec() + .withBearerToken(unauthorizedUser.token) + .post(`/media/image`) + .withQueryParams(params) + .withFile('file', `test/e2e/media/image/artifacts/image.png`) + .expectAppError(ERROR_CODE.FORBIDDEN_NOT_ENOUGH_API_PERMISSIONS, 'API_UPLOAD_MEDIA')); + + it('should fail as directory does not exist', () => + pactum + .spec() + .withBearerToken(user.token) + .post(`/media/image`) + .withQueryParams(params) + .withFile('file', `test/e2e/media/image/artifacts/image.webp`) + .expectAppError(ERROR_CODE.SERVER_DISK_ERROR)); + + describe('should create the annal', () => { + beforeAll(() => { + mkdirSync(`${app().get(ConfigModule).MEDIA_UPLOAD_DIR}/image`, { recursive: true }); + }); + + afterAll(() => { + rmSync(app().get(ConfigModule).MEDIA_UPLOAD_DIR.split('/')[0], { recursive: true }); + }); + + const testFunction = (fileExt: 'png' | 'jpg' | 'avif' | 'tif' | 'webp', rotation: 0 | 1 | 2 | 3) => async () => { + return pactum + .spec() + .withBearerToken(user.token) + .post(`/media/image`) + .withQueryParams({ ...params, rotation }) + .withFile('file', `test/e2e/media/image/artifacts/image.${fileExt}`) + .expectImageMedia({ + width: 256, + height: 256, + isPublic: params.public, + preset: params.preset, + size: JsonLike.INT, + id: JsonLike.UUID, + }); + }; + + it('from a tiff', testFunction('tif', 0)); + it('from a png', testFunction('png', 1)); + it('from a jpg', testFunction('jpg', 2)); + it('from a webp', testFunction('webp', 3)); + it('from a avif', testFunction('avif', 0)); + + it('should upscale to 1080p', async () => { + return pactum + .spec() + .withBearerToken(user.token) + .post(`/media/image`) + .withQueryParams({ + ...params, + preset: 'CUSTOM', + width: 1920, + height: 1080, + }) + .withFile('file', `test/e2e/media/image/artifacts/image.png`) + .expectImageMedia({ + width: 1920, + height: 1080, + isPublic: params.public, + preset: 'CUSTOM', + size: JsonLike.INT, + id: JsonLike.UUID, + }); + }); + + it('should not upscale to more than 1080p', async () => { + return pactum + .spec() + .withBearerToken(user.token) + .post(`/media/image`) + .withQueryParams({ + ...params, + preset: 'CUSTOM', + width: 1921, + height: 1081, + }) + .withFile('file', `test/e2e/media/image/artifacts/image.png`) + .expectAppError(ERROR_CODE.PARAM_TOO_HIGH, 'height, width'); + }); + + it('not from a gif', async () => { + return pactum + .spec() + .withBearerToken(user.token) + .post(`/media/image`) + .withQueryParams(params) + .withFile('file', `test/e2e/media/image/artifacts/image.gif`) + .expectAppError(ERROR_CODE.FILE_INVALID_TYPE, 'image/png, image/jpeg, image/webp, image/avif, image/tiff'); + }); + it('not from a fake png', async () => { + return pactum + .spec() + .withBearerToken(user.token) + .post(`/media/image`) + .withQueryParams(params) + .withFile('file', `test/e2e/media/image/artifacts/image.gif.png`) + .expectAppError(ERROR_CODE.FILE_INVALID_TYPE, 'image/png, image/jpeg, image/webp, image/avif, image/tiff'); + }); + it('but not allow missing files', async () => { + return pactum + .spec() + .withBearerToken(user.token) + .post(`/media/image`) + .withQueryParams(params) + .expectAppError(ERROR_CODE.NO_FILE_PROVIDED); + }); + }); +}); diff --git a/test/e2e/media/index.ts b/test/e2e/media/index.ts new file mode 100644 index 00000000..01700cc3 --- /dev/null +++ b/test/e2e/media/index.ts @@ -0,0 +1,10 @@ +import { E2EAppProvider } from '../../utils/test_utils'; +import { GetMediaE2ESpec } from './image/get-media.e2e-spec'; +import { UploadMediaE2ESpec } from './image/upload-media.e2e-spec'; + +export default function MediaE2ESpec(app: E2EAppProvider) { + describe('Media', () => { + GetMediaE2ESpec(app); + UploadMediaE2ESpec(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 46ebba87..2cceb319 100644 --- a/test/e2e/ue/annals/get-annal-metadata.e2e-spec.ts +++ b/test/e2e/ue/annals/get-annal-metadata.e2e-spec.ts @@ -11,7 +11,7 @@ import { } from '../../../utils/fakedb'; import { e2eSuite } from '../../../utils/test_utils'; import { ERROR_CODE } from '../../../../src/exceptions'; -import { Permission } from '@prisma/client'; +import { Permission } from '../../../../src/prisma/types'; import { PermissionManager } from '../../../../src/utils'; const GetAnnalMetadata = e2eSuite('GET /ue/annals/metadata', (app) => { diff --git a/test/e2e/ue/get.e2e-spec.ts b/test/e2e/ue/get.e2e-spec.ts index 0e56b07c..10d732e4 100644 --- a/test/e2e/ue/get.e2e-spec.ts +++ b/test/e2e/ue/get.e2e-spec.ts @@ -14,7 +14,7 @@ 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 { UserType } from '@prisma/client'; +import { UserType } from '../../../src/prisma/types'; import { FakeUeWithOfs } from 'test/declarations'; const GetE2ESpec = e2eSuite('GET /ue/{ueCode}', (app) => { diff --git a/test/e2e/users/get-user_assos-e2e-spec.ts b/test/e2e/users/get-user_assos-e2e-spec.ts index ab1bbce3..94200bea 100644 --- a/test/e2e/users/get-user_assos-e2e-spec.ts +++ b/test/e2e/users/get-user_assos-e2e-spec.ts @@ -59,6 +59,7 @@ const GetUserAssociationE2ESpec = e2eSuite('GET /users/:userId/associations', (a asso: { ...omit(membership.asso, 'descriptionShortTranslation'), shortDescription: membership.asso.descriptionShortTranslation.fr, + logo: membership.asso.logo ? `/media/image/${membership.asso.logo.id}.webp` : null, }, })); diff --git a/test/e2e/users/update-profile-e2e-spec.ts b/test/e2e/users/update-profile-e2e-spec.ts index 56fba51b..b027e18d 100644 --- a/test/e2e/users/update-profile-e2e-spec.ts +++ b/test/e2e/users/update-profile-e2e-spec.ts @@ -32,7 +32,7 @@ const UpdateProfile = e2eSuite('PATCH /users/current', (app) => { displayAddress: 'ALL_PUBLIC', }) .$expectRegexableJson({ - avatar: user.infos.avatar, + avatar: user.infos.avatarMediaId ? `/media/image/${user.infos.avatarMediaId}.webp` : null, birthday: user.infos.birthday, discord: user.socialNetwork.discord, facebook: 'fbProfile', diff --git a/test/jest.json b/test/jest.json index 3923f8c6..f6ca26d2 100644 --- a/test/jest.json +++ b/test/jest.json @@ -7,5 +7,7 @@ "transform": { "^.+\\.(t|j)s$": "ts-jest" }, - "collectCoverageFrom": ["**/*.ts", "!main.ts"] + "collectCoverageFrom": ["**/*.ts", "!main.ts", "!**/*-res.dto.ts"], + "coverageDirectory": "coverage", + "coverageReporters": ["html", "lcov", "text-summary"] } diff --git a/test/unit/app.spec.ts b/test/unit/app.spec.ts index 42372ff3..0fe934af 100644 --- a/test/unit/app.spec.ts +++ b/test/unit/app.spec.ts @@ -1,15 +1,16 @@ import TimetableServiceUnitSpec from './timetable/timetable.service.spec'; +import LexicalValidationUnitSpec from './lexical/lexical-validation.spec'; +import LexicalGenerationUnitSpec from './lexical/lexical-generation.spec'; import { Test, TestingModule } from '@nestjs/testing'; import { AppModule } from '../../src/app.module'; import '../../src/std.type'; -/* - * Unit testing is currently DISABLED. Remove the .skip in the line below - */ -describe.skip('EtuUTT API unit testing', () => { +describe('EtuUTT API unit testing', () => { let app: TestingModule; beforeAll(async () => { app = await Test.createTestingModule({ imports: [AppModule] }).compile(); }); TimetableServiceUnitSpec(() => app); + LexicalValidationUnitSpec(() => app); + LexicalGenerationUnitSpec(() => app); }); diff --git a/test/unit/lexical/lexical-generation.spec.ts b/test/unit/lexical/lexical-generation.spec.ts new file mode 100644 index 00000000..8b98acf2 --- /dev/null +++ b/test/unit/lexical/lexical-generation.spec.ts @@ -0,0 +1,55 @@ +import { unitSuite } from '../../utils/test_utils'; +import { BUNDLES, LexicalModule } from '../../../src/lexical/lexical.module'; +import { createHeadlessEditor } from '@lexical/headless'; +import { $createParagraphNode, $createTextNode, $getRoot, LexicalEditor } from 'lexical'; + +const LexicalGenerationUnitSpec = unitSuite('Lexical generation', (app) => { + let lexicalModule: LexicalModule; + + beforeAll(() => { + lexicalModule = app().get(LexicalModule); + }); + + const checkExportForBundles = ( + name: string, + bundles: (keyof typeof BUNDLES)[], + test: (editor: LexicalEditor) => void, + result: string, + ) => { + bundles.forEach((bundle) => { + // These steps are skipped as jest does not support yet pure-esm sub-dependencies + describe.skip(name, () => { + it(bundle, () => { + const editor = createHeadlessEditor({ + nodes: BUNDLES['@etuutt/full'], + }); + editor.update(() => { + test(editor); + }); + editor.read(async () => + expect(await lexicalModule.generateHTML(JSON.stringify(editor.getEditorState()), bundle)).toBe(result), + ); + }); + }); + }); + }; + + checkExportForBundles( + 'Paragraph', + ['@etuutt/full', '@etuutt/simple'], + () => $getRoot().append($createParagraphNode().append($createTextNode('Hello World'))), + '

Hello World

', + ); + + checkExportForBundles( + 'Bold text', + ['@etuutt/full', '@etuutt/simple'], + () => + $getRoot().append( + $createParagraphNode().append($createTextNode('Hello '), $createTextNode('World').setFormat('bold')), + ), + '

Hello World

', + ); +}); + +export default LexicalGenerationUnitSpec; diff --git a/test/unit/lexical/lexical-validation.spec.ts b/test/unit/lexical/lexical-validation.spec.ts new file mode 100644 index 00000000..7a207b64 --- /dev/null +++ b/test/unit/lexical/lexical-validation.spec.ts @@ -0,0 +1,157 @@ +import { unitSuite } from '../../utils/test_utils'; +import { BUNDLES, LexicalModule } from '../../../src/lexical/lexical.module'; +import { createHeadlessEditor } from '@lexical/headless'; +import { $createParagraphNode, $createTextNode, $getRoot, LexicalEditor } from 'lexical'; +import { $createCodeHighlightNode, $createCodeNode } from '@lexical/code'; +import { $createHeadingNode, $createQuoteNode } from '@lexical/rich-text'; +import { $createImageNode } from '../../../src/lexical/nodes/ImageNode'; +import { $createColorTextNode } from '../../../src/lexical/nodes/ColorTextNode'; +import { $createAutoLinkNode, $createLinkNode } from '@lexical/link'; +import { $createHorizontalRuleNode } from '@lexical/extension'; +import { $createListItemNode, $createListNode } from '@lexical/list'; +import { $createTableCellNode, $createTableNode, $createTableRowNode } from '@lexical/table'; + +const LexicalValidationUnitSpec = unitSuite('Lexical validation', (app) => { + let lexicalModule: LexicalModule; + + beforeAll(() => { + lexicalModule = app().get(LexicalModule); + }); + + const checkValidityForBundles = ( + name: string, + bundles: Record, + test: (editor: LexicalEditor) => void, + ) => { + Object.entries(bundles).forEach(([bundle, shouldBeValid]) => { + describe(name, () => { + it(bundle, () => { + const editor = createHeadlessEditor({ + nodes: BUNDLES['@etuutt/full'], + }); + editor.update(() => { + test(editor); + }); + editor.read(() => + expect(lexicalModule.isValidLexicalContent(JSON.stringify(editor.getEditorState()), bundle)).toBe( + shouldBeValid, + ), + ); + }); + }); + }); + }; + + checkValidityForBundles( + 'Paragraph', + { + '@etuutt/full': true, + '@etuutt/simple': true, + }, + () => $getRoot().append($createParagraphNode().append($createTextNode('Hello World'))), + ); + + checkValidityForBundles( + 'Paragraph with color', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => $getRoot().append($createParagraphNode().append($createColorTextNode('Hello World').setColor('blue'))), + ); + + checkValidityForBundles( + 'Paragraph with link', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => + $getRoot().append( + $createParagraphNode().append($createTextNode('Hello '), $createLinkNode('World').setURL('https://etu.utt.fr')), + ), + ); + + checkValidityForBundles( + 'Paragraph with autolink', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => + $getRoot().append( + $createParagraphNode().append( + $createTextNode('Hello '), + $createAutoLinkNode('World').setURL('https://etu.utt.fr'), + ), + ), + ); + + checkValidityForBundles( + 'Heading', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => $getRoot().append($createHeadingNode().append($createTextNode('Hello heading'))), + ); + + checkValidityForBundles( + 'Quote', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => $getRoot().append($createQuoteNode().append($createTextNode('Hello quote'))), + ); + + checkValidityForBundles( + 'Code', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => $getRoot().append($createCodeNode().append($createTextNode('Hello '), $createCodeHighlightNode('highlight'))), + ); + + checkValidityForBundles( + 'Image', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => $getRoot().append($createParagraphNode().append($createImageNode('https://etu.utt.fr/test.webp'))), + ); + + checkValidityForBundles( + 'Horizontal rule', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => $getRoot().append($createHorizontalRuleNode()), + ); + + checkValidityForBundles( + 'List', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => $getRoot().append($createListNode().append($createListItemNode().append($createTextNode('Item')))), + ); + + checkValidityForBundles( + 'Table', + { + '@etuutt/full': true, + '@etuutt/simple': false, + }, + () => + $getRoot().append( + $createTableNode().append($createTableRowNode().append($createTableCellNode().append($createTextNode('Cell')))), + ), + ); +}); + +export default LexicalValidationUnitSpec; diff --git a/test/unit/timetable/timetable.service.spec.ts b/test/unit/timetable/timetable.service.spec.ts index e7dd9ee1..0e689a84 100644 --- a/test/unit/timetable/timetable.service.spec.ts +++ b/test/unit/timetable/timetable.service.spec.ts @@ -5,7 +5,8 @@ import * as fakedb from '../../utils/fakedb'; import { createTimetableEntry, createTimetableEntryOverride } from '../../utils/fakedb'; import { faker } from '@faker-js/faker'; -const TimetableServiceUnitSpec = unitSuite('Timetable.service', (app) => { +// This check is skipped, please remove the last argument to enable tests +const TimetableServiceUnitSpec = unitSuite.skip('Timetable.service', (app) => { let timetableService: TimetableService; let prisma: PrismaService; const user1 = fakedb.createUser(app); diff --git a/test/utils/fakedb.ts b/test/utils/fakedb.ts index c368ac9b..179c309c 100644 --- a/test/utils/fakedb.ts +++ b/test/utils/fakedb.ts @@ -34,12 +34,13 @@ import { RawUserPrivacy, RawApiKey, RawApiApplication, + RawImageMedia, } from '../../src/prisma/types'; import { faker } from '@faker-js/faker'; import { AuthService } from '../../src/auth/auth.service'; import { PrismaService } from '../../src/prisma/prisma.service'; import { AppProvider } from './test_utils'; -import { Permission, Sex, TimetableEntryType, UserType } from '@prisma/client'; +import { ImageMediaPreset, Permission, Sex, TimetableEntryType, UserType } from '../../src/prisma/types'; import { CommentStatus } from '../../src/ue/comments/interfaces/comment.interface'; import { UeAnnalFile } from '../../src/ue/annals/interfaces/annal.interface'; import { omit, PermissionManager, pick, translationSelect } from '../../src/utils'; @@ -118,6 +119,7 @@ export type FakeHomepageWidget = Partial; export type FakeApiApplication = Partial> & { owner: { id: string; firstName: string; lastName: string }; }; +export type FakeImageMedia = Partial; export interface FakeEntityMap { assoMembership: { @@ -245,6 +247,10 @@ export interface FakeEntityMap { params: CreateApiApplicationParameter; deps: { owner: FakeUser }; }; + imageMedia: { + entity: FakeImageMedia; + params: CreateImageMediaParameter; + }; } export type CreateUserParameters = FakeUser & { password: string }; @@ -1090,6 +1096,19 @@ export const createApplication = entityFaker( }), ); +export type CreateImageMediaParameter = Omit; +export const createImageMedia = entityFaker( + 'imageMedia', + { + height: faker.number.int({ min: 100, max: 4000 }), + width: faker.number.int({ min: 100, max: 4000 }), + isPublic: faker.datatype.boolean, + size: faker.number.int({ min: 1000, max: 10_000_000 }), + preset: faker.helpers.enumValue(ImageMediaPreset), + }, + async (app, params) => app().get(PrismaService).imageMedia.create({ data: params }), +); + /** * The return type of a fake function, either Promise or FakeEntity depending on whether OnTheFly is true or false */ diff --git a/test/utils/test_utils.ts b/test/utils/test_utils.ts index d338062d..6f222e54 100644 --- a/test/utils/test_utils.ts +++ b/test/utils/test_utils.ts @@ -1,11 +1,10 @@ import { PrismaService } from '../../src/prisma/prisma.service'; +import { PrismaClient } from '../../src/prisma/types'; import { INestApplication } from '@nestjs/common'; import { TestingModule } from '@nestjs/testing'; import { faker } from '@faker-js/faker'; import { ConfigModule } from '../../src/config/config.module'; -import { DMMF } from '@prisma/client/runtime/library'; import { clearUniqueValues, generateDefaultApplication } from '../../prisma/seed/utils'; -import { PrismaClient } from '@prisma/client'; /** * Initializes this file. @@ -52,6 +51,12 @@ function suite(name: string, func: (app: T) => void) { func(app); }); } +suite.skip = + (name: string, func: (app: T) => void) => + (app: T) => + describe.skip(name, () => { + func(app); + }); /** * Creates a suite for e2e testing. It works the same as {@link describe}, but it cleans the database before each suite. @@ -69,6 +74,7 @@ export const unitSuite = suite; export const JsonLike = { STRING: Symbol('string'), UUID: Symbol('uuid'), + INT: Symbol('int'), DATE: /^\d{4}-[01]\d-[0-3]\d(?:T[0-2]\d:[0-5]\d:[0-5]\d[.,]\d+Z)?$/, // dateTime from pactum-matchers doesn't ms }; @@ -81,46 +87,11 @@ export const Dummies = { * @param prisma The prisma service instance. */ export async function cleanDb(prisma: PrismaService | PrismaClient) { - // We can't delete each table one by one, because of foreign key constraints - const tablesCleared = [] as string[]; - // _runtimeDataModel.models basically contains a JS-ified version of the schema.prisma - for (const modelName of Object.keys((prisma as any)._runtimeDataModel.models) as string[]) { - // Check the table hasn't been already cleaned - if (tablesCleared.includes(modelName)) continue; - await clearTableWithCascade(prisma, modelName, tablesCleared); - } -} - -/** - * Clears a table, and all the tables that have a foreign key constraint on it. - * This should only be used by {@link cleanDb}. - * @param prisma The prisma service instance. - * @param modelName The name of the model to clear. - * @param tablesCleared The list of tables that have already been cleared. - */ -async function clearTableWithCascade(prisma: PrismaService | PrismaClient, modelName: string, tablesCleared: string[]) { - // No, the full type of the model is not even exported :( - // (type RuntimeDataModel in prisma/client/runtime/library) - const model: Omit = (prisma as any)._runtimeDataModel.models[modelName]; - for (const field of Object.values(model.fields)) { - // First, check that the field is a relation, and not a normal String, or Int, or any normal SQL type - // We then check that this is not a self-referencing relation, to avoid infinite loops - // The way we verify that this is not the part of the relation that is referenced is by checking the length of relationFromFields : if it has a length, the table contains the FK, if not, that's the other table - // Plot twist : Prisma allows for ManyToMany relations. That means that, to avoid infinitely looping, we verify the other relation in the opposite direction (with the same name) holds the FK - if ( - field.kind === 'object' && - field.type !== modelName && - field.relationFromFields.length === 0 && - !tablesCleared.includes(field.type) && - (prisma as any)._runtimeDataModel.models[field.type].fields.find( - (f: DMMF.Field) => f.relationName === field.relationName, - ).relationFromFields.length !== 0 - ) { - // After all these checks, simply delete rows from the other table first to avoid foreign key constraint errors - await clearTableWithCascade(prisma, field.type, tablesCleared); - } - } - // And finally, once it's safe to do it, delete the rows, and mark it as cleared - await prisma[modelName].deleteMany(); - tablesCleared.push(modelName); + return prisma.$transaction(async (tx) => { + await tx.$executeRawUnsafe(`SET FOREIGN_KEY_CHECKS = 0`); + // _runtimeDataModel.models basically contains a JS-ified version of the schema.prisma + for (const modelName of Object.keys((tx as any)._runtimeDataModel.models) as string[]) + await tx[modelName].deleteMany(); + await tx.$executeRawUnsafe(`SET FOREIGN_KEY_CHECKS = 1`); + }); } diff --git a/tsconfig.json b/tsconfig.json index e3d90c59..7d4a0aeb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,10 +6,13 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, - "target": "ES2022", + "target": "es2022", "sourceMap": true, "outDir": "./dist", - "baseUrl": "./", + "paths": { + "src/*": ["./src/*"], + "test/*": ["./test/*"] + }, "incremental": true, "skipLibCheck": true, "strictNullChecks": false, @@ -18,9 +21,9 @@ "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": false, "esModuleInterop": true, - "resolveJsonModule": true, + "resolveJsonModule": true }, "ts-node": { "files": true - }, + } }