diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..db4c6d9b67 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +dist +node_modules \ No newline at end of file diff --git a/.env.sample b/.env.sample index 1f901e4b7b..34f30d8c42 100644 --- a/.env.sample +++ b/.env.sample @@ -1,22 +1,29 @@ -# 👋 Welcome, we're glad you're setting up an installation of Talawa-api. Copy this +# 👋 Welcome, we're glad you're setting up an installation of Talawa-api. Copy this # file to .env or set the variables in your local environment manually. # Generate a unique random key, you can use `openssl rand -hex 32` in terminal + ACCESS_TOKEN_SECRET= + # Generate a unique random key, you can use `openssl rand -hex 32` in terminal + REFRESH_TOKEN_SECRET= -# if you are using DOCKER use this mongodb url -# mongodb://mongo:27017/talawa-api -# if you are using hosted mongodb, mongodb connection string will look like this -# mongodb+srv://:@/?retryWrites=true&w=majority -# for local instance use this connection string -# mongodb://localhost:27017/?retryWrites=true&w=majority +# Please read about mongodb connection string here :- https://www.mongodb.com/docs/v5.2/reference/connection-string/ + +# This is the default mongodb connection string for the mongodb docker container that's created along with talawa-api docker container. +# Use this as the value for `MONGO_DB_URL` environment variables when you're using the docker approach. + +# mongodb://talawa_mongodb:27017/talawa-api?retryWrites=true&w=majority + + +# This environment variable is used to provide the mongodb connection string to talawa-api. MONGO_DB_URL= + # Get the google recaptcha secret key from google recaptcha admin or https://www.google.com/recaptcha/admin/create # from here for reCAPTCHA v2 and "I'm not a robot" Checkbox, and paste the key here. # Note: In domains, fill localhost diff --git a/.eslintignore b/.eslintignore index b367f16681..7f1734b6c8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,6 @@ -node_modules .github .vscode - -old-api \ No newline at end of file +build +coverage +node_modules +src/generated \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 9290a5953d..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = { - env: { - commonjs: true, - es2021: true, - node: true, - 'jest/globals': true, - }, - extends: [ - 'eslint:recommended', - 'plugin:prettier/recommended', - 'plugin:jest/recommended', - ], - parserOptions: { - ecmaVersion: 12, - }, - rules: { - indent: ['error', 2], - 'linebreak-style': 0, - quotes: ['error', 'single', 'avoid-escape'], - semi: ['error', 'always'], - eqeqeq: 'error', - 'no-trailing-spaces': 'error', - 'object-curly-spacing': ['error', 'always'], - 'arrow-spacing': ['error', { before: true, after: true }], - 'jest/no-disabled-tests': 'warn', - 'jest/no-focused-tests': 'error', - 'jest/no-identical-title': 'error', - 'jest/prefer-to-have-length': 'warn', - 'jest/valid-expect': 'error', - }, - plugins: ['jest'], -}; diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000000..7e7813f8c1 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,64 @@ +{ + "env": { + "es2022": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:prettier/recommended" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "processor": "@graphql-eslint/graphql" + }, + { + "files": [ + "*.graphql" + ], + "parser": "@graphql-eslint/eslint-plugin", + "plugins": [ + "@graphql-eslint" + ] + } + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "root": true, + "rules": { + "eqeqeq": [ + "error", + "always" + ], + "linebreak-style": [ + "error", + "unix" + ], + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_", + "destructuredArrayIgnorePattern": "^_", + "varsIgnorePattern": "^_" + } + ], + "quotes": [ + "error", + "double", + { + "allowTemplateLiterals": true, + "avoidEscape": true + } + ] + } +} \ No newline at end of file diff --git a/.github/workflows/codeql-codescan.yml b/.github/workflows/codeql-codescan.yml index 0d9807780a..8f4111478a 100644 --- a/.github/workflows/codeql-codescan.yml +++ b/.github/workflows/codeql-codescan.yml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript'] + language: [ 'typescript'] steps: - name: Checkout repository diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 49d84467e6..a514fafde8 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -21,9 +21,9 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install Dependencies - run: yarn + run: npm ci - name: Run ESLint and Prettier - run: yarn lint + run: npm run lint Count-lines-of-code: name: Total number of lines in every file should not be more than 400 @@ -33,37 +33,37 @@ jobs: - uses: actions/checkout@v2 - run: chmod +x ./.github/workflows/countline.py - run: | - ./.github/workflows/countline.py --exclude_directories tests + ./.github/workflows/countline.py --exclude_directories __tests__ Code-Formatter: name: Formats the code runs-on: ubuntu-latest needs: Linter steps: - - name: Checkout - uses: actions/checkout@v2 - with: - # This is important to fetch the changes to the previous commit - fetch-depth: 0 - - name: Prettify code - uses: creyD/prettier_action@v3.3 - with: - same_commit: True - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout + uses: actions/checkout@v2 + with: + # This is important to fetch the changes to the previous commit + fetch-depth: 0 + - name: Prettify code + uses: creyD/prettier_action@v3.3 + with: + same_commit: True + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} JSDocs: - name : "JSDocs comments and pipeline" - runs-on : ubuntu-latest + name: 'JSDocs comments and pipeline' + runs-on: ubuntu-latest needs: Code-Formatter steps: - uses: actions/checkout@v2 - - name : "Check whether comments exists for JSDocs" + - name: 'Check whether comments exists for JSDocs' run: | chmod +x ./.github/workflows/check-jsdocs-comment.py ./.github/workflows/check-jsdocs-comment.py - - name : "Run JSDocs" + - name: 'Run JSDocs' if: env.RUN_JSDOCS == 'True' run: echo "Run JSdocs :${{ env.RUN_JSDOCS }}" @@ -74,15 +74,14 @@ jobs: strategy: matrix: node-version: [14.x] - mongodb-version: ['4.4'] services: mongo: - image: mongo + image: mongo:4.4 options: >- - --health-cmd mongo - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-cmd mongo + --health-interval 10s + --health-timeout 5s + --health-retries 10 ports: - 27017:27017 env: @@ -91,35 +90,30 @@ jobs: REFRESH_TOKEN_SECRET: 96d41e144e63475f7f753735b50305cd2857cc41c2f2570babdb948c10b77bc5 steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + - name: Checkout repository + uses: actions/checkout@v2 - - name: Install dependencies - run: npm install + - name: Set up Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 - - name: Start the Application - run: npm run start-test-server-in-action + - name: Install dependencies + run: npm ci - - name: Sleep for 10s - uses: juliangruber/sleep-action@v1 - with: - time: 10s + - name: Sleep for 10s + uses: juliangruber/sleep-action@v1 + with: + time: 10s - - name: Run the tests - run: npm run test + - name: Run the tests + run: npm run test - - name: Present current coverage in PR - uses: codecov/codecov-action@v2.1.0 - with: - verbose: true - - name: Stop the Application - run: npm run stop-test-server-in-action + - name: Present current coverage in PR + uses: codecov/codecov-action@v2.1.0 + with: + verbose: true - - name: Test acceptable level of code coverage - uses: VeryGoodOpenSource/very_good_coverage@v1.1.1 - with: - path: "./coverage/lcov.info" - min_coverage: 46.5 + - name: Test acceptable level of code coverage + uses: VeryGoodOpenSource/very_good_coverage@v1.1.1 + with: + path: './coverage/lcov.info' + min_coverage: 46.5 diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index b4dc2782cc..3f0a3822d7 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -3,7 +3,7 @@ # # NOTE! # -# Please read the README.md file in this directory that defines what should +# Please read the README.md file in this directory that defines what should # be placed in this file # ############################################################################## @@ -14,14 +14,13 @@ name: Push Workflow on: push: branches: - - '**' + - '**' jobs: - -############################################################################## -# This section is added so that the most recent and valid level of -# code coverage (post PR merge) is reported -############################################################################## + ############################################################################## + # This section is added so that the most recent and valid level of + # code coverage (post PR merge) is reported + ############################################################################## Code-Coverage: name: Testing Application @@ -29,47 +28,40 @@ jobs: strategy: matrix: node-version: [14.x] - mongodb-version: ['4.4'] services: mongo: - image: mongo + image: mongo:4.4 options: >- - --health-cmd mongo - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-cmd mongo + --health-interval 10s + --health-timeout 5s + --health-retries 10 ports: - 27017:27017 env: MONGO_DB_URL: mongodb://localhost:27017/talawa-test-db ACCESS_TOKEN_SECRET: eeb2137b1961a3da9e3736ea4a9ed1e77cb33a4fad8a153d364c2f04ec50eab7 REFRESH_TOKEN_SECRET: 96d41e144e63475f7f753735b50305cd2857cc41c2f2570babdb948c10b77bc5 - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 - - name: Install dependencies - run: npm install + steps: + - name: Checkout repository + uses: actions/checkout@v2 - - name: Start the Application - run: npm run start-test-server-in-action + - name: Set up Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 - - name: Sleep for 10s - uses: juliangruber/sleep-action@v1 - with: - time: 10s + - name: Install dependencies + run: npm ci - - name: Run the tests - run: npm run test + - name: Sleep for 10s + uses: juliangruber/sleep-action@v1 + with: + time: 10s - - name: Stop the Application - run: npm run stop-test-server-in-action + - name: Run the tests + run: npm run test - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v2.1.0 - with: - verbose: true + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v2.1.0 + with: + verbose: true diff --git a/.gitignore b/.gitignore index 3e418801d2..ec9f442b4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,20 @@ -node_modules/ +node_modules nodemon.json -.idea/ +.idea .env -images/ +images .vscode -# Added as the documentation only refers to npm, not yarn. +# Added as the documentation only refers to npm, not yarn and pnpm. yarn.lock +pnpm-lock.yaml # We don't want to have code coverage data stored in the repo as it is dynamic -coverage/ +coverage + +# We don't want to push emitted production build of talawa-api to github. +# Since it will only be needed in CI/CD and production environment it +# should be generated on the fly at that time. +build serviceAccountKey.json \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index b367f16681..7f1734b6c8 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,6 @@ -node_modules .github .vscode - -old-api \ No newline at end of file +build +coverage +node_modules +src/generated \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 2c0fc022ce..0000000000 --- a/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "endOfLine": "auto" -} \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..168d9d2a0c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "endOfLine": "auto" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 545f9fe6f1..71e1a848e0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ No one should fear voicing their opinion. Respones must be respectful. If you are ready to start contributing code right away, get ready! -1. Join our Slack and introduce yourself. See details on how to join below. +1. Join our Slack and introduce yourself. See details on how to join below in the Community section. 1. This repository has its own dedicated channel. 1. There are many persons on the various channels who are willing to assist you in getting started. 1. Take a look at our issues (**_after reading our guidelines below_**): @@ -99,11 +99,6 @@ The process of proposing a change to Talawa API can be summarized as: 1. The coverage rate will be visible on the penultimate line of the `genhtml` command's output. 1. The `genhtml` command is part of the linux `lcov` package. Similar packages can be found for Windows and MacOS. 1. The currently acceptable coverage rate can be found in the [GitHub Pull Request file](.github/workflows/pull-request.yml). Search for the value below the line containing `min_coverage`. - 1. _Testing Individual Files_ - 1. You can test an individual file and get its code coverage by running this command: - ``` - npm run file-coverage --functionfile=path/to/file --testfile=path/to/test/file - ``` 1. _Creating your code coverage account_ 1. You can also see your code coverage online for your fork of the repo. This is provided by `codecov.io` 1. Go to this link: `https://app.codecov.io/gh/XXXX/YYYY` where XXXX is your GitHub account username and YYYY is the name of the repository @@ -131,5 +126,5 @@ If you are participating in the GitHub Externship, please read more about us and ## Community There are many ways to communicate with the community. -1. The Palisadoes Foundation has a Slack channel where members can assist with support and clarification. Visit [slack.palisadoes.org](http://slack.palisadoes.org) to join our slack channel. +1. The Palisadoes Foundation has a Slack channel where members can assist with support and clarification. Visit the [Talawa GitHub repository home page](https://github.com/PalisadoesFoundation/talawa) for the link to join our slack channel. 1. We also have a technical email list run by [freelists.org](https://www.freelists.org/). Search for "palisadoes" and join. Members on this list are also periodically added to our marketing email list that focuses on less technical aspects of our work. diff --git a/Dockerfile b/Dockerfile index 0277c6fec2..2bb3df48df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,23 @@ -FROM node:14 +# Pulls the node.js v16 docker image from docker hub. +FROM node:16 +# Sets '/usr/src/app' as the default working directory to be used +# by the subsequent commands and the generated container. That means +# './' will correspond to '/usr/src/app/' inside the container onwards. WORKDIR /usr/src/app +# Copies 'package.json' and 'package-lock.json' files. +# '*'is a wildcard character and here it means any filenames +# starting with 'package' and ending with '.json'. COPY package*.json ./ +# Installs all the dependencies listed in 'package.json' file under the +# node_modules folder in the 'WORKDIR' directory inside the container. RUN npm install +# Copies all the remaining files/folders to 'WORKDIR' except 'node_modules' +# and 'dist' folders because they're listed in '.dockerignore' file. COPY . . -EXPOSE 4000 - -CMD ["npm", "start"] \ No newline at end of file +# Runs the dev command to start the node.js server in development mode. +CMD ["npm","run","dev"] \ No newline at end of file diff --git a/INSTALLATION.md b/INSTALLATION.md index a5829fd2cf..5b4e3d8914 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -1,202 +1,218 @@ -# Installation +# Setting Up The MongoDB Database -Talawa API is a `node.js` application. It can be setup to run via `Docker` or node's default package manager `npm`. +A running instance of mongodb and it's connection string is required for making use of talawa-api. We're listing a few common approaches to get a running instance of mongodb database :- -## Docker +1. Using a hosted(remote) mongodb database :- MongoDB Atlas is the easiest way to get a running instance of mongodb database. We will be making use of mongodb atlas though mongodb can be hosted using other platforms as well. Follow the setup guide on [mongodb atlas docs](https://www.mongodb.com/docs/atlas/getting-started/). If you want to use some other mongodb hosted database please do your own research. -Follow these steps to get the api running using Docker. +2. Using a mongodb database installed on your local system natively :- Follow the setup guide on [mongodb docs](https://www.mongodb.com/docs/manual/administration/install-community/) for your respective operating system. -**Note:** Docker downloads a lot of large images, if you are short on storage or with slow internet connection prefer using standard development installation. +3. Using a containerized mongodb docker container on your local system :- Follow the setup guide using this [video tutorial](https://www.youtube.com/watch?v=uklyCSKQ1Po). -1. Install [Docker](https://docs.docker.com/get-docker/) if you have not installed it. -2. Clone this repo to your local machine +**Note:** If you are running mongodb on a remote system, either a cloud service or a system under your control, then ensure you have provided the correct access permissions and firewall openings for the VM/server/service where the mongodb is hosted. + +Paste the connection string for your database as the value for environment variable named `MONGO_DB_URL` inside the `.env` file present in the root directory of this application. + +# Talawa-api Installation + +Talawa API is mainly written and built using `node.js` and `typescript`. We are providing some common approaches to set it up on your system. + +## Installation using the standard method + +Pre-requisites :- + +1. A running mongodb database connection string. Refer to `Setting Up The MongoDB Database` section for more information. + +2. NodeJS installed on your local system(version 14 or above preferrable). It's best to make use of a node version manager to manage nodejs versions on your system. Two popular node version managers currently are [fnm](https://github.com/Schniz/fnm) and [nvm](https://github.com/nvm-sh/nvm). Follow the setup guide for either of them and install NodeJS. + +Follow these steps to get the API running :- + +1. Clone this repo to your local machine :- git clone https://github.com/PalisadoesFoundation/talawa-api + +2. Change directory to cloned folder :- + cd talawa-api + +3. Install the npm packages required by talawa-api :- + npm install -3. Talawa-API uses a configuration file named `.env` in the root directory. It is not a part of the repo and you will need to create it. There is a sample configuration file named `.env.sample` in the root diretory. Create a new `.env` file by copying the contents of the `.env.sample` file. +4. Talawa-API uses a configuration file named `.env` in the root directory. It is not a part of the repo and you will need to create it. There is a sample configuration file named `.env.sample` in the root directory. Create a new `.env` file by copying the contents of the `.env.sample` file. - cp .env .env.sample + cp .env.sample .env -4. Generate an `ACCESS_TOKEN_SECRET` using the `openessl` command below and copy the result to the `ACCESS_TOKEN_SECRET` section of the `.env` file. +5. Generate an `ACCESS_TOKEN_SECRET` using the `openessl` command below and copy the result to the `ACCESS_TOKEN_SECRET` section of the `.env` file. openssl rand -hex 32 -5. Generate an `REFRESH_TOKEN_SECRET` using the `openessl` command below and copy the result to the `REFRESH_TOKEN_SECRET` section of the `.env` file. +6. Generate an `REFRESH_TOKEN_SECRET` using the `openessl` command below and copy the result to the `REFRESH_TOKEN_SECRET` section of the `.env` file. openssl rand -hex 32 -6. Add the MongoDB URL that `talawa-api` will need to use to get access to the database to the `.env`. file. +7. Follow the `Setting Up Mongodb Database` section to set up a mongodb database and get a mongodb database connection string. Paste that connection string in `.env` file under the variable named `MONGO_DB_URL`. + +8. Get the google recaptcha secret key from `google-recaptcha-admin` for reCAPTCHA v2 and "I'm not a robot" Checkbox, and copy the key to the `RECAPTCHA_SECRET_KEY` section of the `.env` file. + + **Note**: In domains, fill localhost + + Google-recaptcha-admin: https://www.google.com/recaptcha/admin/create + +9. Enter the gmail credentials for sending mails to the users. In `MAIL_USERNAME` enter email address and in `MAIL_PASSWORD` enter app password. To get the app password, follow these steps: + + - Go to your Google Account, https://myaccount.google.com/ + - Select Security. + - Under "Signing in to Google," select App Passwords. + - At the bottom, choose Select app and choose the app you using and then Select device and choose the device you’re using and then Generate. + - The App Password is the 16-character code in the yellow bar on your device. + - Paste that App Password in `MAIL_PASSWORD`. + + **Note**: You must setup two factor authentication in order to allow the app password. - mongodb://mongo:27017/talawa-api - - - where - - `mongodb` is the name of the container. - - `mongo` is the name of the image which is also the database. - - `27017` is the port to connect to the `mongo` container. - - `talawa-api` is the name of the database. - + For more info refer, https://support.google.com/accounts/answer/185833 -7. When finished, your `.env` file should have the following fields filled in. +10. When finished, your `.env` file should have the following fields filled in :- - ACCESS_TOKEN_SECRET - REFRESH_TOKEN_SECRET - MONGO_DB_URL + - RECAPTCHA_SECRET_KEY + - MAIL_USERNAME + - MAIL_PASSWORD Please review the contents of the `.env.sample` file for additional details. -8. Build the `docker` image that will support `talawa-api` +11. Install the required dependencies. - sudo docker-compose build + npm install -9. Start the `docker` container. This is the command you will use to start the server after reboots. +12. To test the notification service create a new firebase project: - sudo docker-compose up +- In the Firebase console, open Settings > [Service Accounts](https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk). -10. To stop the `docker` container, this is the command you can use. +- Click Generate New Private Key, then confirm by clicking Generate Key. - sudo docker-compose down +- Securely store the JSON file containing the key. -## Standard Installation +- Run the following command to set the key in the environment variable: -Follow these steps to get the API running. + - Linux/macOS: `export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"` -1. Install these **mandatory** dependencies if you don't already have them: - - [Nodejs](https://nodejs.org/en/) - -2. Install these **optional** dependencies if you don't already have them: - - Talawa-API requires a `MongoDB` database. This can be provided either as a hosted `MongoDB` cloud service or installed locally on your machine. - * If you are going to install the database on a **system you control**, then follow these [MongoDB installation instructions](https://docs.mongodb.com/manual/administration/install-community/) - * If you don't have enough resources on your system or looking to store data using a **cloud service**, then you can use [MongoDB Atlas](https://docs.atlas.mongodb.com/). This method doesn't require any installation and it's free to use. To configure the database service, go through their [docs](https://docs.atlas.mongodb.com/). - * **Note:** If you are running MongoDB on a remote system, either a cloud service or a system under your control, then ensure you have provided the correct access permissions and firewall openings for the VM/server/service where the MongoDB is hosted. -3. Clone this repo to your local machine + - Windows: `$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"` - git clone https://github.com/PalisadoesFoundation/talawa-api - cd talawa-api - npm install + 1. Install the [Firebase CLI](https://firebase.google.com/docs/cli#install_the_firebase_cli). + 2. Copy the `firebase_options.dart` file as it will be modified. + 3. Run the following commands in the project directory of talawa mobile app: -4. Talawa-API uses a configuration file named `.env` in the root directory. It is not a part of the repo and you will need to create it. There is a sample configuration file named `.env.sample` in the root diretory. Create a new `.env` file by copying the contents of the `.env.sample` file. + - `firebase login` + - `dart pub global activate flutterfire_cli` + - `flutterfire configure` - cp .env.sample .env + 4. Select the project you created in the Firebase console in step 2. + 5. Add iOS and android platforms to the project. + 6. Overwrite the `firebase_options.dart` file if asked so. + 7. Copy the keys to `.env` file, for how to set keys refer to `.env.sample` file. + 8. Undo the changes made to the `firebase_options.dart` file by pasting the old content from step 2. -5. Generate an `ACCESS_TOKEN_SECRET` using the `openessl` command below and copy the result to the `ACCESS_TOKEN_SECRET` section of the `.env` file. +13. The command below will run the talawa-api server in development environment. - openssl rand -hex 32 + npm run dev -6. Generate an `REFRESH_TOKEN_SECRET` using the `openessl` command below and copy the result to the `REFRESH_TOKEN_SECRET` section of the `.env` file. +14. To stop the server use this keybind in the terminal where the above command is executed :- - openssl rand -hex 32 + CTRL + C -7. Add the MongoDB URL that `talawa-api` will need to use to get access to the database to the `.env`. file. +## Installation using docker - - If MongoDB is running on your local system for data storage then the generic format of the URL would be: +Pre-requisites :- - ``` - mongodb://localhost:27017/?retryWrites=true&w=majority - ``` - * Where `` is the name of the MongoDB database. +1. `Docker` installed on your system. Follow the setup guide on [docker docs](https://docs.docker.com/get-docker/). +2. Free port `27017` on your system's localhost. - - If you are using a MongoDB cloud service for data storage, then the generic format of the URL would be: +**Note:** We are not listing every possible thing you need to know about docker in the following steps. We expect you to have minimum working knowledge with docker if you're using this approach. If you don't know anything about docker it's better to either learn about docker first or go with the steps mentioned in the section `Installation using standard method`. Also docker downloads a lot of large images, if you are short on storage or with slow internet connection prefer using the standard method. - ``` - mongodb+srv://:@/?retryWrites=true&w=majority - ``` - - * Where: - - `` is your cloud service user name. - - `` is your cloud service password. - - `` is your cloud service server URL. - - `` is your cloud service database name. - * Your cloud service may call this URL a `connect` string. Search for the word `connect` in your online database dashboard to find it. +Follow these steps to get the api running :- -8. Get the google recaptcha secret key from `google-recaptcha-admin` for reCAPTCHA v2 and "I'm not a robot" Checkbox, and copy the key to the `RECAPTCHA_SECRET_KEY` section of the `.env` file. +1. Clone this repo to your local machine -- Note: In domains, fill localhost + git clone https://github.com/PalisadoesFoundation/talawa-api - Google-recaptcha-admin: https://www.google.com/recaptcha/admin/create +2. Change directory to cloned folder :- + + cd talawa-api + +3. Talawa-API uses a configuration file named `.env` in the root directory. It is not a part of the repo and you will need to create it. There is a sample configuration file named `.env.sample` in the root directory. Create a new `.env` file by copying the contents of the `.env.sample` file. + + cp .env.sample .env + +4. Generate an `ACCESS_TOKEN_SECRET` using the `openessl` command below and copy the result to the `ACCESS_TOKEN_SECRET` section of the `.env` file. + + openssl rand -hex 32 + +5. Generate an `REFRESH_TOKEN_SECRET` using the `openessl` command below and copy the result to the `REFRESH_TOKEN_SECRET` section of the `.env` file. -9. Enter the gmail credentials for sending mails to the users. In `MAIL_USERNAME` enter email address and in `MAIL_PASSWORD` enter app password. -- To get the app password, follow these steps: - - * Go to your Google Account, https://myaccount.google.com/ - * Select Security. - * Under "Signing in to Google," select App Passwords. - * At the bottom, choose Select app and choose the app you using and then Select device and choose the device you’re using and then Generate. - * The App Password is the 16-character code in the yellow bar on your device. - * Paste that App Password in `MAIL_PASSWORD`. + openssl rand -hex 32 + +6. We have written the docker configuration in such a way that along with talawa-api mongodb is also started inside a docker container. Both of them communicate with each other internally. This is done so you don't have to manually set up a mongodb database and then connect it to the talawa-api docker container yourselves. Within the docker environment this mongodb container is accessible using this connection string :- + + mongodb://talawa_mongodb:27017/?retryWrites=true&w=majority -- Note: You must setup two factor authentication in order to allow the app password. + We have mapped this mongodb docker container to port `27017` of your system's localhost. Make sure that port `27017` is free on your system's localhost or you'll get an error. To access this mongodb container on your system use this connection string :- -- For more info refer, https://support.google.com/accounts/answer/185833 + mongodb://localhost:27017/?retryWrites=true&w=majority -10. When finished, your `.env` file should have the following fields filled in. +7. When finished, your `.env` file should have the following fields filled in. - ACCESS_TOKEN_SECRET - REFRESH_TOKEN_SECRET - MONGO_DB_URL - - RECAPTCHA_SECRET_KEY - - MAIL_USERNAME - - MAIL_PASSWORD Please review the contents of the `.env.sample` file for additional details. -11. Install required node packages. +8. Build the `docker` image that will support talawa-api - npm install - -12. To test the notification service create a new firebase project: + sudo docker-compose build -- In the Firebase console, open Settings > [Service Accounts](https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk). +9. To start the talawa-api docker container run this command while being in the talawa-api folder directory :- -- Click Generate New Private Key, then confirm by clicking Generate Key. + sudo docker-compose up -- Securely store the JSON file containing the key. + **Note** :- There is one caveat here. `Docker` might not automatically start each time you reboot your system. To start docker after a system reboot on linux machines run this command :- -- Run the following command to set the key in the environment variable: - - - Linux/macOS: `export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"` - - - Windows: `$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"` + sudo systemctl start docker -- - 1. Install the [Firebase CLI](https://firebase.google.com/docs/cli#install_the_firebase_cli). - 2. Copy the `firebase_options.dart` file as it will be modified. - 3. Run the following commands in the project directory of talawa mobile app: - - `firebase login` - - `dart pub global activate flutterfire_cli` - - `flutterfire configure` - 4. Select the project you created in the Firebase console in step 2. - 5. Add iOS and android platforms to the project. - 6. Overwrite the `firebase_options.dart` file if asked so. - 7. Copy the keys to `.env` file, for how to set keys refer to `.env.sample` file. - 8. Undo the changes made to the `firebase_options.dart` file by pasting the old content from step 2. + To make docker start automatically after system reboots follow [start docker on boot](https://docs.docker.com/engine/install/linux-postinstall/#configure-docker-to-start-on-boot) guide. -13. Start the `talawa-api` server using the below command in the same terminal. +10. To stop the talawa-api docker container run this command while being in the talawa-api folder directory :- - npm start + sudo docker-compose down -14. To stop the server after making changes. Press `CTRL + C` in the terminal where the above command is executed. +## Automated Installation -# Testing -You can run `talawa-api` tests using this command -``` -npm run test -``` +This method will automate most of the work needed for setting up talawa-api. -## Automated Installation +Pre-requisites :- -This method installs the Talawa API automatically. Follow these steps to get the API running using ```npm```. +1. A running mongodb database connection string. -1. Install these dependencies if you don't already have them - - [MongoDB](https://docs.mongodb.com/manual/administration/install-community/) - - [NodeJS](https://nodejs.org/en/)
- Note:If you do not have MongoDB on your own system, you can proceed with the connection string. Please ensure the right access permissions and firewall openings for the VM/server where the MongoDB is hosted. -2. Clone this repo to your local machine +2. NodeJS installed on your local system(version 14 or above preferrable). It's best to make use of a node version manager to manage nodejs versions on your system. Two popular node version managers currently are [fnm](https://github.com/Schniz/fnm) and [nvm](https://github.com/nvm-sh/nvm). Follow the setup guide for either of them and install NodeJS. + +Follow these steps to get the api running :- + +1. Clone this repo to your local machine using this command :- + + git clone https://github.com/PalisadoesFoundation/talawa-api + +2. Change directory into the cloned folder using this command :- + + cd talawa-api + +3. Run the setup command :- + + npm run setup + +# Testing - ```sh - git clone https://github.com/PalisadoesFoundation/talawa-api - cd talawa-api - npm run setup - ``` +You can run the tests for talawa-api using this command :- + npm run test diff --git a/__tests__/resolvers/DirectChat/creator.spec.ts b/__tests__/resolvers/DirectChat/creator.spec.ts new file mode 100644 index 0000000000..b50f523e8d --- /dev/null +++ b/__tests__/resolvers/DirectChat/creator.spec.ts @@ -0,0 +1,73 @@ +import "dotenv/config"; +import { creator as creatorResolver } from "../../../src/lib/resolvers/DirectChat/creator"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_DirectChat, + DirectChat, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChat: Interface_DirectChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testDirectChat = await DirectChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> DirectChat -> creator", () => { + it(`returns user object for parent.creator`, async () => { + const parent = testDirectChat.toObject(); + + const creatorPayload = await creatorResolver?.(parent, {}, {}); + + const creator = await User.findOne({ + _id: testDirectChat.creator, + }).lean(); + + expect(creatorPayload).toEqual(creator); + }); +}); diff --git a/__tests__/resolvers/DirectChat/messages.spec.ts b/__tests__/resolvers/DirectChat/messages.spec.ts new file mode 100644 index 0000000000..a83ace2acc --- /dev/null +++ b/__tests__/resolvers/DirectChat/messages.spec.ts @@ -0,0 +1,84 @@ +import "dotenv/config"; +import { messages as messagesResolver } from "../../../src/lib/resolvers/DirectChat/messages"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_DirectChat, + DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChat: Interface_DirectChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testDirectChat = await DirectChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + }); + + await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUser._id, + receiver: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> DirectChat -> messages", () => { + it(`returns user object for parent.messages`, async () => { + const parent = testDirectChat.toObject(); + + const messagesPayload = await messagesResolver?.(parent, {}, {}); + + const messages = await DirectChatMessage.find({ + _id: { + $in: testDirectChat.messages, + }, + }).lean(); + + expect(messagesPayload).toEqual(messages); + }); +}); diff --git a/__tests__/resolvers/DirectChat/organization.spec.ts b/__tests__/resolvers/DirectChat/organization.spec.ts new file mode 100644 index 0000000000..90fc21b28d --- /dev/null +++ b/__tests__/resolvers/DirectChat/organization.spec.ts @@ -0,0 +1,73 @@ +import "dotenv/config"; +import { organization as organizationResolver } from "../../../src/lib/resolvers/DirectChat/organization"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_DirectChat, + DirectChat, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChat: Interface_DirectChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testDirectChat = await DirectChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> DirectChat -> organization", () => { + it(`returns user object for parent.organization`, async () => { + const parent = testDirectChat.toObject(); + + const organizationPayload = await organizationResolver?.(parent, {}, {}); + + const organization = await Organization.findOne({ + _id: testDirectChat.organization, + }).lean(); + + expect(organizationPayload).toEqual(organization); + }); +}); diff --git a/__tests__/resolvers/DirectChat/users.spec.ts b/__tests__/resolvers/DirectChat/users.spec.ts new file mode 100644 index 0000000000..03a83db40e --- /dev/null +++ b/__tests__/resolvers/DirectChat/users.spec.ts @@ -0,0 +1,84 @@ +import "dotenv/config"; +import { users as usersResolver } from "../../../src/lib/resolvers/DirectChat/users"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_DirectChat, + DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChat: Interface_DirectChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testDirectChat = await DirectChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + }); + + await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUser._id, + receiver: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> DirectChat -> users", () => { + it(`returns user object for parent.users`, async () => { + const parent = testDirectChat.toObject(); + + const usersPayload = await usersResolver?.(parent, {}, {}); + + const users = await User.find({ + _id: { + $in: testDirectChat.users, + }, + }).lean(); + + expect(usersPayload).toEqual(users); + }); +}); diff --git a/__tests__/resolvers/DirectChatMessage/directChatMessageBelongsTo.spec.ts b/__tests__/resolvers/DirectChatMessage/directChatMessageBelongsTo.spec.ts new file mode 100644 index 0000000000..02f09aec42 --- /dev/null +++ b/__tests__/resolvers/DirectChatMessage/directChatMessageBelongsTo.spec.ts @@ -0,0 +1,86 @@ +import "dotenv/config"; +import { directChatMessageBelongsTo as directChatMessageBelongsToResolver } from "../../../src/lib/resolvers/DirectChatMessage/directChatMessageBelongsTo"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_DirectChatMessage, + DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChatMessage: Interface_DirectChatMessage & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + const testDirectChat = await DirectChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); + + testDirectChatMessage = await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUser._id, + receiver: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> DirectChatMessage -> directChatMessageBelongsTo", () => { + it(`returns directChat object for parent.directChatMessageBelongsTo`, async () => { + const parent = testDirectChatMessage.toObject(); + + const directChatMessageBelongsToPayload = + await directChatMessageBelongsToResolver?.(parent, {}, {}); + + const directChatMessageBelongsTo = await DirectChat.findOne({ + _id: testDirectChatMessage.directChatMessageBelongsTo, + }).lean(); + + expect(directChatMessageBelongsToPayload).toEqual( + directChatMessageBelongsTo + ); + }); +}); diff --git a/__tests__/resolvers/DirectChatMessage/receiver.spec.ts b/__tests__/resolvers/DirectChatMessage/receiver.spec.ts new file mode 100644 index 0000000000..c5a9611f0a --- /dev/null +++ b/__tests__/resolvers/DirectChatMessage/receiver.spec.ts @@ -0,0 +1,83 @@ +import "dotenv/config"; +import { receiver as receiverResolver } from "../../../src/lib/resolvers/DirectChatMessage/receiver"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_DirectChatMessage, + DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChatMessage: Interface_DirectChatMessage & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + const testDirectChat = await DirectChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); + + testDirectChatMessage = await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUser._id, + receiver: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> DirectChatMessage -> receiver", () => { + it(`returns user object for parent.receiver`, async () => { + const parent = testDirectChatMessage.toObject(); + + const receiverPayload = await receiverResolver?.(parent, {}, {}); + + const receiver = await User.findOne({ + _id: testDirectChatMessage.receiver, + }).lean(); + + expect(receiverPayload).toEqual(receiver); + }); +}); diff --git a/__tests__/resolvers/DirectChatMessage/sender.spec.ts b/__tests__/resolvers/DirectChatMessage/sender.spec.ts new file mode 100644 index 0000000000..e10436c719 --- /dev/null +++ b/__tests__/resolvers/DirectChatMessage/sender.spec.ts @@ -0,0 +1,83 @@ +import "dotenv/config"; +import { sender as senderResolver } from "../../../src/lib/resolvers/DirectChatMessage/sender"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_DirectChatMessage, + DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChatMessage: Interface_DirectChatMessage & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + const testDirectChat = await DirectChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); + + testDirectChatMessage = await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUser._id, + receiver: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> DirectChatMessage -> sender", () => { + it(`returns user object for parent.sender`, async () => { + const parent = testDirectChatMessage.toObject(); + + const senderPayload = await senderResolver?.(parent, {}, {}); + + const sender = await User.findOne({ + _id: testDirectChatMessage.sender, + }).lean(); + + expect(senderPayload).toEqual(sender); + }); +}); diff --git a/__tests__/resolvers/GroupChat/creator.spec.ts b/__tests__/resolvers/GroupChat/creator.spec.ts new file mode 100644 index 0000000000..a0ae29d921 --- /dev/null +++ b/__tests__/resolvers/GroupChat/creator.spec.ts @@ -0,0 +1,74 @@ +import "dotenv/config"; +import { creator as creatorResolver } from "../../../src/lib/resolvers/GroupChat/creator"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_GroupChat, + GroupChat, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testGroupChat: Interface_GroupChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testGroupChat = await GroupChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> GroupChat -> creator", () => { + it(`returns user object for parent.creator`, async () => { + const parent = testGroupChat.toObject(); + + const creatorPayload = await creatorResolver?.(parent, {}, {}); + + const creator = await User.findOne({ + _id: testGroupChat.creator, + }).lean(); + + expect(creatorPayload).toEqual(creator); + }); +}); diff --git a/__tests__/resolvers/GroupChat/messages.spec.ts b/__tests__/resolvers/GroupChat/messages.spec.ts new file mode 100644 index 0000000000..dc2fd8240f --- /dev/null +++ b/__tests__/resolvers/GroupChat/messages.spec.ts @@ -0,0 +1,84 @@ +import "dotenv/config"; +import { messages as messagesResolver } from "../../../src/lib/resolvers/GroupChat/messages"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_GroupChat, + GroupChat, + GroupChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testGroupChat: Interface_GroupChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testGroupChat = await GroupChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); + + await GroupChatMessage.create({ + groupChatMessageBelongsTo: testGroupChat._id, + sender: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> GroupChat -> messages", () => { + it(`returns user objects for parent.messages`, async () => { + const parent = testGroupChat.toObject(); + + const messagesPayload = await messagesResolver?.(parent, {}, {}); + + const messages = await GroupChatMessage.find({ + _id: { + $in: testGroupChat.messages, + }, + }).lean(); + + expect(messagesPayload).toEqual(messages); + }); +}); diff --git a/__tests__/resolvers/GroupChat/organization.spec.ts b/__tests__/resolvers/GroupChat/organization.spec.ts new file mode 100644 index 0000000000..f9032f66c3 --- /dev/null +++ b/__tests__/resolvers/GroupChat/organization.spec.ts @@ -0,0 +1,74 @@ +import "dotenv/config"; +import { organization as organizationResolver } from "../../../src/lib/resolvers/GroupChat/organization"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_GroupChat, + GroupChat, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testGroupChat: Interface_GroupChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testGroupChat = await GroupChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> GroupChat -> organization", () => { + it(`returns user objects for parent.organization`, async () => { + const parent = testGroupChat.toObject(); + + const organizationPayload = await organizationResolver?.(parent, {}, {}); + + const organization = await Organization.findOne({ + _id: testGroupChat.organization, + }).lean(); + + expect(organizationPayload).toEqual(organization); + }); +}); diff --git a/__tests__/resolvers/GroupChat/users.spec.ts b/__tests__/resolvers/GroupChat/users.spec.ts new file mode 100644 index 0000000000..57466d1d21 --- /dev/null +++ b/__tests__/resolvers/GroupChat/users.spec.ts @@ -0,0 +1,76 @@ +import "dotenv/config"; +import { users as usersResolver } from "../../../src/lib/resolvers/GroupChat/users"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_GroupChat, + GroupChat, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testGroupChat: Interface_GroupChat & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testGroupChat = await GroupChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> GroupChat -> users", () => { + it(`returns user objects for parent.users`, async () => { + const parent = testGroupChat.toObject(); + + const usersPayload = await usersResolver?.(parent, {}, {}); + + const users = await User.find({ + _id: { + $in: testGroupChat.users, + }, + }).lean(); + + expect(usersPayload).toEqual(users); + }); +}); diff --git a/__tests__/resolvers/GroupChatMessage/groupChatMessageBelongsTo.spec.ts b/__tests__/resolvers/GroupChatMessage/groupChatMessageBelongsTo.spec.ts new file mode 100644 index 0000000000..a1f1ae38b1 --- /dev/null +++ b/__tests__/resolvers/GroupChatMessage/groupChatMessageBelongsTo.spec.ts @@ -0,0 +1,83 @@ +import "dotenv/config"; +import { groupChatMessageBelongsTo as groupChatMessageBelongsToResolver } from "../../../src/lib/resolvers/GroupChatMessage/groupChatMessageBelongsTo"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_GroupChatMessage, + GroupChat, + GroupChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testGroupChatMessage: Interface_GroupChatMessage & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + const testGroupChat = await GroupChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); + + testGroupChatMessage = await GroupChatMessage.create({ + groupChatMessageBelongsTo: testGroupChat._id, + sender: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> GroupChatMessage -> groupChatMessageBelongsTo", () => { + it(`returns groupChatMessageBelongsTo object for parent.groupChatMessageBelongsTo`, async () => { + const parent = testGroupChatMessage.toObject(); + + const groupChatMessageBelongsToPayload = + await groupChatMessageBelongsToResolver?.(parent, {}, {}); + + const groupChatMessageBelongsTo = await GroupChat.findOne({ + _id: testGroupChatMessage.groupChatMessageBelongsTo, + }).lean(); + + expect(groupChatMessageBelongsToPayload).toEqual(groupChatMessageBelongsTo); + }); +}); diff --git a/__tests__/resolvers/GroupChatMessage/sender.spec.ts b/__tests__/resolvers/GroupChatMessage/sender.spec.ts new file mode 100644 index 0000000000..04cb8a269d --- /dev/null +++ b/__tests__/resolvers/GroupChatMessage/sender.spec.ts @@ -0,0 +1,82 @@ +import "dotenv/config"; +import { sender as senderResolver } from "../../../src/lib/resolvers/GroupChatMessage/sender"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_GroupChatMessage, + GroupChat, + GroupChatMessage, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testGroupChatMessage: Interface_GroupChatMessage & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + const testGroupChat = await GroupChat.create({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + title: "title", + }); + + testGroupChatMessage = await GroupChatMessage.create({ + groupChatMessageBelongsTo: testGroupChat._id, + sender: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> GroupChatMessage -> sender", () => { + it(`returns sender object for parent.sender`, async () => { + const parent = testGroupChatMessage.toObject(); + + const senderPayload = await senderResolver?.(parent, {}, {}); + + const sender = await User.findOne({ + _id: testGroupChatMessage.sender, + }).lean(); + + expect(senderPayload).toEqual(sender); + }); +}); diff --git a/__tests__/resolvers/MembershipRequest/organization.spec.ts b/__tests__/resolvers/MembershipRequest/organization.spec.ts new file mode 100644 index 0000000000..96de0f4ff1 --- /dev/null +++ b/__tests__/resolvers/MembershipRequest/organization.spec.ts @@ -0,0 +1,72 @@ +import "dotenv/config"; +import { organization as organizationResolver } from "../../../src/lib/resolvers/MembershipRequest/organization"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + MembershipRequest, + Interface_MembershipRequest, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testMembershipRequest: Interface_MembershipRequest & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testMembershipRequest = await MembershipRequest.create({ + organization: testOrganization._id, + user: testUser._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> MembershipRequest -> organization", () => { + it(`returns organization object for parent.organization`, async () => { + const parent = testMembershipRequest.toObject(); + + const organizationPayload = await organizationResolver?.(parent, {}, {}); + + const organization = await Organization.findOne({ + _id: testMembershipRequest.organization, + }).lean(); + + expect(organizationPayload).toEqual(organization); + }); +}); diff --git a/__tests__/resolvers/MembershipRequest/user.spec.ts b/__tests__/resolvers/MembershipRequest/user.spec.ts new file mode 100644 index 0000000000..180717d881 --- /dev/null +++ b/__tests__/resolvers/MembershipRequest/user.spec.ts @@ -0,0 +1,72 @@ +import "dotenv/config"; +import { user as userResolver } from "../../../src/lib/resolvers/MembershipRequest/user"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + MembershipRequest, + Interface_MembershipRequest, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testMembershipRequest: Interface_MembershipRequest & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testMembershipRequest = await MembershipRequest.create({ + organization: testOrganization._id, + user: testUser._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> MembershipRequest -> user", () => { + it(`returns user object for parent.user`, async () => { + const parent = testMembershipRequest.toObject(); + + const userPayload = await userResolver?.(parent, {}, {}); + + const user = await User.findOne({ + _id: testMembershipRequest.user, + }).lean(); + + expect(userPayload).toEqual(user); + }); +}); diff --git a/__tests__/resolvers/Mutation/acceptAdmin.spec.ts b/__tests__/resolvers/Mutation/acceptAdmin.spec.ts new file mode 100644 index 0000000000..29c4507432 --- /dev/null +++ b/__tests__/resolvers/Mutation/acceptAdmin.spec.ts @@ -0,0 +1,110 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationAcceptAdminArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { acceptAdmin as acceptAdminResolver } from "../../../src/lib/resolvers/Mutation/acceptAdmin"; +import { USER_NOT_AUTHORIZED, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> acceptAdmin", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationAcceptAdminArgs = { + id: testUser.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await acceptAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws Error if user with _id === context.userId is not a SUPERADMIN`, async () => { + try { + const args: MutationAcceptAdminArgs = { + id: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await acceptAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.id`, async () => { + try { + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + userType: "SUPERADMIN", + }, + } + ); + + const args: MutationAcceptAdminArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await acceptAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`makes user with _id === args.id adminApproved and returns true`, async () => { + const args: MutationAcceptAdminArgs = { + id: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const acceptAdminPayload = await acceptAdminResolver?.({}, args, context); + + expect(acceptAdminPayload).toEqual(true); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["adminApproved"]) + .lean(); + + expect(updatedTestUser?.adminApproved).toEqual(true); + }); +}); diff --git a/__tests__/resolvers/Mutation/acceptMembershipRequest.spec.ts b/__tests__/resolvers/Mutation/acceptMembershipRequest.spec.ts new file mode 100644 index 0000000000..a21d86fc3e --- /dev/null +++ b/__tests__/resolvers/Mutation/acceptMembershipRequest.spec.ts @@ -0,0 +1,281 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + MembershipRequest, + Interface_MembershipRequest, +} from "../../../src/lib/models"; +import { MutationAcceptMembershipRequestArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { acceptMembershipRequest as acceptMembershipRequestResolver } from "../../../src/lib/resolvers/Mutation/acceptMembershipRequest"; +import { + MEMBERSHIP_REQUEST_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_ALREADY_MEMBER, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testMembershipRequest: Interface_MembershipRequest & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + visibleInSearch: true, + }); + + testMembershipRequest = await MembershipRequest.create({ + user: testUser._id, + organization: testOrganization._id, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + membershipRequests: testMembershipRequest._id, + }, + } + ); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> acceptMembershipRequest", () => { + it(`throws NotFoundError if no membershipRequest exists with _id === args.membershipRequestId`, async () => { + try { + const args: MutationAcceptMembershipRequestArgs = { + membershipRequestId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await acceptMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(MEMBERSHIP_REQUEST_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === membershipRequest.organization + for membershipRequest with _id === args.membershipRequestId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + organization: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationAcceptMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser.id, + }; + + await acceptMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === membershipRequest.user + for membershipRequest with _id === args.membershipRequestId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + organization: testOrganization._id, + user: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationAcceptMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser.id, + }; + + await acceptMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not an + admin of organization with _id === membershipRequest.organization for + membershipRequest with _id === args.membershipRequestId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + user: testUser.id, + }, + } + ); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationAcceptMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser.id, + }; + + await acceptMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws ConflictError if user with _id === membershipRequest.user is already + a member of organization with _id === membershipRequest.organization for membershipRequest + with _id === args.membershipRequestId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + members: testUser._id, + }, + } + ); + + const args: MutationAcceptMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser.id, + }; + + await acceptMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_ALREADY_MEMBER); + } + }); + + it(`accepts the membershipRequest and returns it`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + members: [], + }, + } + ); + + const args: MutationAcceptMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser.id, + }; + + const acceptMembershipRequestPayload = + await acceptMembershipRequestResolver?.({}, args, context); + + expect(acceptMembershipRequestPayload).toEqual( + testMembershipRequest.toObject() + ); + + const updatedTestOrganization = await Organization.findOne({ + _id: testOrganization._id, + }) + .select(["members", "membershipRequests"]) + .lean(); + + expect(updatedTestOrganization).toEqual( + expect.objectContaining({ + members: expect.arrayContaining([testUser._id]), + membershipRequests: expect.arrayContaining([]), + }) + ); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["joinedOrganizations", "membershipRequests"]) + .lean(); + + expect(updatedTestUser).toEqual( + expect.objectContaining({ + joinedOrganizations: expect.arrayContaining([testOrganization._id]), + membershipRequests: expect.arrayContaining([]), + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/addLanguageTranslation.spec.ts b/__tests__/resolvers/Mutation/addLanguageTranslation.spec.ts new file mode 100644 index 0000000000..fcc9986eb3 --- /dev/null +++ b/__tests__/resolvers/Mutation/addLanguageTranslation.spec.ts @@ -0,0 +1,93 @@ +import "dotenv/config"; +import { addLanguageTranslation as addLanguageTranslationResolver } from "../../../src/lib/resolvers/Mutation/addLanguageTranslation"; +import { connect, disconnect } from "../../../src/db"; +import { MutationAddLanguageTranslationArgs } from "../../../src/generated/graphqlCodegen"; +import { Language } from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +const randomValue = nanoid().toLowerCase(); + +const testArgs: MutationAddLanguageTranslationArgs[] = [ + { + data: { + en_value: `english${randomValue}`, + translation_lang_code: `en${randomValue}`, + translation_value: `english${randomValue}`, + }, + }, + { + data: { + en_value: `english${randomValue}`, + translation_lang_code: `en${randomValue}`, + translation_value: `notEnglish${randomValue}`, + }, + }, + { + data: { + en_value: `english${randomValue}`, + translation_lang_code: `chi${randomValue}`, + translation_value: `英语${randomValue}`, + }, + }, +]; + +beforeAll(async () => { + await connect(); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> addLanguageTranslation", () => { + it(`if no language exists with en === args.data.en_value creates language + and returns it`, async () => { + const args: MutationAddLanguageTranslationArgs = testArgs[0]; + + const addLanguageTranslationPayload = + await addLanguageTranslationResolver?.({}, args, {}); + + const createdLanguage = await Language.findOne({ + en: testArgs[0].data.en_value, + }).lean(); + + expect(addLanguageTranslationPayload).toEqual(createdLanguage); + }); + + it(`throws ConflictError if translation.lang_code === args.data.translation_lang_code + for language with en === args.data.en_value`, async () => { + try { + const args: MutationAddLanguageTranslationArgs = testArgs[1]; + + await addLanguageTranslationResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual("Translation already present"); + } + }); + + it(`updates language.translation with new values if + translation.lang_code !== args.data.translation_lang_code for existing language with + en === args.en_value`, async () => { + const args: MutationAddLanguageTranslationArgs = testArgs[2]; + + const addLanguageTranslationPayload = + await addLanguageTranslationResolver?.({}, args, {}); + + expect(addLanguageTranslationPayload).toEqual( + expect.objectContaining({ + en: testArgs[0].data.en_value, + translation: expect.arrayContaining([ + expect.objectContaining({ + lang_code: testArgs[0].data.translation_lang_code, + value: testArgs[0].data.translation_value, + }), + expect.objectContaining({ + lang_code: testArgs[2].data.translation_lang_code, + value: testArgs[2].data.translation_value, + }), + ]), + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/addOrganizationImage.spec.ts b/__tests__/resolvers/Mutation/addOrganizationImage.spec.ts new file mode 100644 index 0000000000..c47719dcfb --- /dev/null +++ b/__tests__/resolvers/Mutation/addOrganizationImage.spec.ts @@ -0,0 +1,150 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationAddOrganizationImageArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { addOrganizationImage as addOrganizationImageResolver } from "../../../src/lib/resolvers/Mutation/addOrganizationImage"; +import { + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + blockedUsers: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> addOrganizationImage", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationAddOrganizationImageArgs = { + organizationId: "", + file: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await addOrganizationImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.organizationId`, async () => { + try { + const args: MutationAddOrganizationImageArgs = { + organizationId: Types.ObjectId().toString(), + file: "", + }; + + const context = { + userId: testUser.id, + }; + + await addOrganizationImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId + is not an admin of organization with _id === args.organizationId`, async () => { + try { + const args: MutationAddOrganizationImageArgs = { + organizationId: testOrganization.id, + file: "", + }; + + const context = { + userId: testUser.id, + }; + + await addOrganizationImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + // it(`updates organization's image and returns the updated organization`, async () => { + // await Organization.updateOne( + // { + // _id: testOrganization._id, + // }, + // { + // $set: { + // image: 'image', + // }, + // } + // ); + + // const args: MutationAddOrganizationImageArgs = { + // organizationId: testOrganization.id, + // file: '', + // }; + + // const context = { + // userId: testUser._id, + // }; + + // const addOrganizationImagePayload = await addOrganizationImageResolver?.( + // {}, + // args, + // context + // ); + + // const updatedTestOrganization = await Organization.findOne({ + // _id: testOrganization._id, + // }).lean(); + + // expect(addOrganizationImagePayload).toEqual(updatedTestOrganization); + + // expect(addOrganizationImagePayload?.image).toEqual(null); + // }); +}); diff --git a/__tests__/resolvers/Mutation/addUserImage.spec.ts b/__tests__/resolvers/Mutation/addUserImage.spec.ts new file mode 100644 index 0000000000..3d6f885e71 --- /dev/null +++ b/__tests__/resolvers/Mutation/addUserImage.spec.ts @@ -0,0 +1,80 @@ +import "dotenv/config"; +import { + // Document, + Types, +} from "mongoose"; +// import { Interface_User, User } from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { MutationAddUserImageArgs } from "../../../src/generated/graphqlCodegen"; +import { addUserImage as addUserImageResolver } from "../../../src/lib/resolvers/Mutation/addUserImage"; +import { USER_NOT_FOUND } from "../../../src/constants"; +// import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +// let testUser:Interface_User & Document + +beforeAll(async () => { + await connect(); + + // testUser = await User.create({ + // email: `email${nanoid().toLowerCase()}@gmail.com`, + // password: "password", + // firstName: "firstName", + // lastName: "lastName", + // appLanguageCode: "en", + // }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> addUserImage", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationAddUserImageArgs = { + file: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await addUserImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + // it(`sets image field to null for organization with _id === args.organizationId + // and returns the updated organization`, async () => { + // await User.updateOne( + // { + // _id: testUser._id, + // }, + // { + // $set: { + // image: 'image', + // }, + // } + // ); + + // const args: MutationAddUserImageArgs = { + // file: '', + // }; + + // const context = { + // userId: testUser._id, + // }; + + // const addUserImagePayload = await addUserImageResolver?.({}, args, context); + + // const updatedTestUser = await User.findOne({ + // _id: testUser._id, + // }).lean(); + + // expect(addUserImagePayload).toEqual(updatedTestUser); + + // expect(addUserImagePayload?.image).toEqual(null); + // }); +}); diff --git a/__tests__/resolvers/Mutation/addUserToGroupChat.spec.ts b/__tests__/resolvers/Mutation/addUserToGroupChat.spec.ts new file mode 100644 index 0000000000..11aa3c0cce --- /dev/null +++ b/__tests__/resolvers/Mutation/addUserToGroupChat.spec.ts @@ -0,0 +1,245 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + GroupChat, + Interface_GroupChat, + GroupChatMessage, +} from "../../../src/lib/models"; +import { MutationAddUserToGroupChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { addUserToGroupChat as addUserToGroupChatResolver } from "../../../src/lib/resolvers/Mutation/addUserToGroupChat"; +import { + CHAT_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_ALREADY_MEMBER, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testGroupChat: Interface_GroupChat & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testGroupChat = await GroupChat.create({ + title: "title", + users: [testUser._id], + creator: testUser._id, + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> addUserToGroupChat", () => { + it(`throws NotFoundError if no groupChat exists with _id === args.chatId`, async () => { + try { + const args: MutationAddUserToGroupChatArgs = { + chatId: Types.ObjectId().toString(), + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await addUserToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === groupChat.organization + for groupChat with _id === args.chatId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat!._id, + }, + { + $set: { + organization: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationAddUserToGroupChatArgs = { + chatId: testGroupChat.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await addUserToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is + not an admin of organization with _id === groupChat.organization for groupChat + with _id === args.chatId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat!._id, + }, + { + $set: { + organization: testOrganization._id, + }, + } + ); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationAddUserToGroupChatArgs = { + chatId: testGroupChat.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await addUserToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.userId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationAddUserToGroupChatArgs = { + chatId: testGroupChat.id, + userId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await addUserToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws ConflictError if user with _id === args.userId is already a member + of groupChat with _id === args.chatId`, async () => { + try { + const args: MutationAddUserToGroupChatArgs = { + chatId: testGroupChat.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await addUserToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_ALREADY_MEMBER); + } + }); + + it(`deletes the groupChat with _id === args.chatId and returns it`, async () => { + await GroupChat.updateOne( + { + _id: testGroupChat._id, + }, + { + $set: { + users: [], + }, + } + ); + + const args: MutationAddUserToGroupChatArgs = { + chatId: testGroupChat.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const addUserToGroupChatPayload = await addUserToGroupChatResolver?.( + {}, + args, + context + ); + + expect(addUserToGroupChatPayload).toEqual(testGroupChat!.toObject()); + + const testDeletedGroupChatMessages = await GroupChatMessage.find({ + groupChatMessageBelongsTo: testGroupChat!._id, + }).lean(); + + expect(testDeletedGroupChatMessages).toEqual([]); + }); +}); diff --git a/__tests__/resolvers/Mutation/adminRemoveEvent.spec.ts b/__tests__/resolvers/Mutation/adminRemoveEvent.spec.ts new file mode 100644 index 0000000000..c5b8cd2de4 --- /dev/null +++ b/__tests__/resolvers/Mutation/adminRemoveEvent.spec.ts @@ -0,0 +1,235 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + Interface_Event, + Event, +} from "../../../src/lib/models"; +import { MutationAdminRemoveEventArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { adminRemoveEvent as adminRemoveEventResolver } from "../../../src/lib/resolvers/Mutation/adminRemoveEvent"; +import { + EVENT_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testEvent = await Event.create({ + title: "title", + description: "description", + allDay: true, + startDate: new Date(), + recurring: true, + isPublic: true, + isRegisterable: true, + creator: testUser._id, + admins: [testUser._id], + registrants: [], + organization: testOrganization._id, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + eventAdmin: testEvent._id, + createdEvents: testEvent._id, + registeredEvents: testEvent._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> adminRemoveEvent", () => { + it(`throws NotFoundError if no event exists with _id === args.id`, async () => { + try { + const args: MutationAdminRemoveEventArgs = { + eventId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await adminRemoveEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === event.organization + for event with _id === args.eventId`, async () => { + try { + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $set: { + organization: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationAdminRemoveEventArgs = { + eventId: testEvent.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await adminRemoveEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $set: { + organization: testOrganization._id, + }, + } + ); + + const args: MutationAdminRemoveEventArgs = { + eventId: testEvent.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await adminRemoveEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not an admin + of organization with _id === event.organization for event with _id === args.eventId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationAdminRemoveEventArgs = { + eventId: testEvent.id, + }; + + const context = { + userId: testUser.id, + }; + + await adminRemoveEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`removes event with _id === args.eventId and returns it`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationAdminRemoveEventArgs = { + eventId: testEvent.id, + }; + + const context = { + userId: testUser.id, + }; + + const adminRemoveEventPayload = await adminRemoveEventResolver?.( + {}, + args, + context + ); + + expect(adminRemoveEventPayload).toEqual(testEvent.toObject()); + + const testUpdatedUser = await User.findOne({ + _id: testUser._id, + }) + .select(["createdEvents", "eventAdmin", "registeredEvents"]) + .lean(); + + expect(testUpdatedUser).toEqual( + expect.objectContaining({ + createdEvents: expect.arrayContaining([]), + eventAdmin: expect.arrayContaining([]), + registeredEvents: expect.arrayContaining([]), + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/adminRemoveGroup.spec.ts b/__tests__/resolvers/Mutation/adminRemoveGroup.spec.ts new file mode 100644 index 0000000000..43e062f74f --- /dev/null +++ b/__tests__/resolvers/Mutation/adminRemoveGroup.spec.ts @@ -0,0 +1,213 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + GroupChat, + Interface_GroupChat, +} from "../../../src/lib/models"; +import { MutationAdminRemoveGroupArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { adminRemoveGroup as adminRemoveGroupResolver } from "../../../src/lib/resolvers/Mutation/adminRemoveGroup"; +import { + CHAT_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testGroupChat: Interface_GroupChat & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testGroupChat = await GroupChat.create({ + title: "title", + users: [testUser._id], + creator: testUser._id, + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> adminRemoveGroup", () => { + it(`throws NotFoundError if no groupChat exists with _id === args.groupId`, async () => { + try { + const args: MutationAdminRemoveGroupArgs = { + groupId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await adminRemoveGroupResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === group.organization for + group with _id === args.groupId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat._id, + }, + { + $set: { + organization: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationAdminRemoveGroupArgs = { + groupId: testGroupChat.id, + }; + + const context = { + userId: testUser.id, + }; + + await adminRemoveGroupResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat._id, + }, + { + $set: { + organization: testOrganization._id, + }, + } + ); + + const args: MutationAdminRemoveGroupArgs = { + groupId: testGroupChat.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await adminRemoveGroupResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if for user with _id === context.userId is not an + admin of orgnanization with _id === args.organizationId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat._id, + }, + { + $set: { + organization: testOrganization._id, + }, + } + ); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationAdminRemoveGroupArgs = { + groupId: testGroupChat.id, + }; + + const context = { + userId: testUser.id, + }; + + await adminRemoveGroupResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`deletes the post and returns it`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationAdminRemoveGroupArgs = { + groupId: testGroupChat.id, + }; + + const context = { + userId: testUser.id, + }; + + const adminRemoveGroupPayload = await adminRemoveGroupResolver?.( + {}, + args, + context + ); + + expect(adminRemoveGroupPayload).toEqual(testGroupChat.toObject()); + }); +}); diff --git a/__tests__/resolvers/Mutation/adminRemovePost.spec.ts b/__tests__/resolvers/Mutation/adminRemovePost.spec.ts new file mode 100644 index 0000000000..9c4f28e413 --- /dev/null +++ b/__tests__/resolvers/Mutation/adminRemovePost.spec.ts @@ -0,0 +1,201 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Post, + Post, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationAdminRemovePostArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { adminRemovePost as adminRemovePostResolver } from "../../../src/lib/resolvers/Mutation/adminRemovePost"; +import { + ORGANIZATION_NOT_FOUND, + POST_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testPost: Interface_Post & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + posts: testPost._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> adminRemovePost", () => { + it(`throws NotFoundError if no organization exists with _id === args.organizationId`, async () => { + try { + const args: MutationAdminRemovePostArgs = { + organizationId: Types.ObjectId().toString(), + postId: "", + }; + + const context = { + userId: testUser.id, + }; + + await adminRemovePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationAdminRemovePostArgs = { + organizationId: testOrganization.id, + postId: testPost.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await adminRemovePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if for user with _id === context.userId is not an + admin of orgnanization with _id === args.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationAdminRemovePostArgs = { + organizationId: testOrganization.id, + postId: testPost.id, + }; + + const context = { + userId: testUser.id, + }; + + await adminRemovePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no post exists with _id === args.postId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationAdminRemovePostArgs = { + organizationId: testOrganization.id, + postId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await adminRemovePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(POST_NOT_FOUND); + } + }); + + it(`deletes the post and returns it`, async () => { + const args: MutationAdminRemovePostArgs = { + organizationId: testOrganization.id, + postId: testPost.id, + }; + + const context = { + userId: testUser.id, + }; + + const adminRemovePostPayload = await adminRemovePostResolver?.( + {}, + args, + context + ); + + const updatedTestOrganization = await Organization.findOne({ + _id: testOrganization._id, + }) + .select(["posts"]) + .lean(); + + expect(updatedTestOrganization?.posts).toEqual([]); + + expect(adminRemovePostPayload).toEqual(testPost.toObject()); + }); +}); diff --git a/__tests__/resolvers/Mutation/blockPluginCreationBySuperadmin.spec.ts b/__tests__/resolvers/Mutation/blockPluginCreationBySuperadmin.spec.ts new file mode 100644 index 0000000000..b7e41ab0ee --- /dev/null +++ b/__tests__/resolvers/Mutation/blockPluginCreationBySuperadmin.spec.ts @@ -0,0 +1,111 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationBlockPluginCreationBySuperadminArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { blockPluginCreationBySuperadmin as blockPluginCreationBySuperadminResolver } from "../../../src/lib/resolvers/Mutation/blockPluginCreationBySuperadmin"; +import { USER_NOT_AUTHORIZED, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> blockPluginCreationBySuperadmin", () => { + it(`throws NotFoundError if no user exists with with _id === args.userId`, async () => { + try { + const args: MutationBlockPluginCreationBySuperadminArgs = { + blockUser: false, + userId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await blockPluginCreationBySuperadminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationBlockPluginCreationBySuperadminArgs = { + blockUser: false, + userId: testUser.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await blockPluginCreationBySuperadminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is not + a SUPERADMIN`, async () => { + try { + const args: MutationBlockPluginCreationBySuperadminArgs = { + blockUser: false, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await blockPluginCreationBySuperadminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`depending on args.blockUser blocks/unblocks plugin creation for user + with _id === args.userId and returns the user`, async () => { + await User.updateOne( + { + _id: testUser._id, + }, + { + userType: "SUPERADMIN", + } + ); + + const args: MutationBlockPluginCreationBySuperadminArgs = { + blockUser: true, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const blockPluginCreationBySuperadminPayload = + await blockPluginCreationBySuperadminResolver?.({}, args, context); + + const testUpdatedTestUser = await User.findOne({ + _id: testUser.id, + }).lean(); + + expect(blockPluginCreationBySuperadminPayload).toEqual(testUpdatedTestUser); + }); +}); diff --git a/__tests__/resolvers/Mutation/blockUser.spec.ts b/__tests__/resolvers/Mutation/blockUser.spec.ts new file mode 100644 index 0000000000..4a549f4c12 --- /dev/null +++ b/__tests__/resolvers/Mutation/blockUser.spec.ts @@ -0,0 +1,195 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationBlockUserArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { blockUser as blockUserResolver } from "../../../src/lib/resolvers/Mutation/blockUser"; +import { + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> blockUser", () => { + it(`throws NotFoundError if no organization exists with with _id === args.organizationId`, async () => { + try { + const args: MutationBlockUserArgs = { + organizationId: Types.ObjectId().toString(), + userId: "", + }; + + const context = { + userId: testUser.id, + }; + + await blockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.userId`, async () => { + try { + const args: MutationBlockUserArgs = { + organizationId: testOrganization.id, + userId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await blockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is not + an admin of the organization with _id === args.organizationId`, async () => { + try { + const args: MutationBlockUserArgs = { + organizationId: testOrganization.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await blockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws UnauthorizedError if user with _id === args.userId is already blocked + from organization with _id === args.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + blockedUsers: testUser._id, + }, + } + ); + + await User.updateOne( + { + _id: testUser.id, + }, + { + $push: { + adminFor: testOrganization._id, + }, + } + ); + + const args: MutationBlockUserArgs = { + organizationId: testOrganization.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await blockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`blocks the user with _id === args.userId from the organization with + _id === args.organizationId and returns the blocked user`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + blockedUsers: [], + }, + } + ); + + const args: MutationBlockUserArgs = { + organizationId: testOrganization.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const blockUserPayload = await blockUserResolver?.({}, args, context); + + const testUpdatedTestUser = await User.findOne({ + _id: testUser.id, + }) + .select(["-password"]) + .lean(); + + expect(blockUserPayload).toEqual(testUpdatedTestUser); + + const testUpdatedOrganization = await Organization.findOne({ + _id: testOrganization._id, + }) + .select(["blockedUsers"]) + .lean(); + + expect(testUpdatedOrganization?.blockedUsers).toEqual([testUser._id]); + }); +}); diff --git a/__tests__/resolvers/Mutation/cancelMembershipRequest.spec.ts b/__tests__/resolvers/Mutation/cancelMembershipRequest.spec.ts new file mode 100644 index 0000000000..6e1ceaffcf --- /dev/null +++ b/__tests__/resolvers/Mutation/cancelMembershipRequest.spec.ts @@ -0,0 +1,244 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + MembershipRequest, + Interface_MembershipRequest, +} from "../../../src/lib/models"; +import { MutationCancelMembershipRequestArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { cancelMembershipRequest as cancelMembershipRequestResolver } from "../../../src/lib/resolvers/Mutation/cancelMembershipRequest"; +import { + MEMBERSHIP_REQUEST_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: (Interface_User & Document) | null; +let testOrganization: + | (Interface_Organization & Document) + | null; +let testMembershipRequest: Interface_MembershipRequest & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testMembershipRequest = await MembershipRequest.create({ + user: testUser._id, + organization: testOrganization._id, + }); + + testUser = await User.findOneAndUpdate( + { + _id: testUser._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + }, + { + new: true, + } + ); + + testOrganization = await Organization.findOneAndUpdate( + { + _id: testOrganization._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + }, + { + new: true, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> cancelMembershipRequest", () => { + it(`throws NotFoundError if no membershipRequest exists with _id === args.membershipRequestId`, async () => { + try { + const args: MutationCancelMembershipRequestArgs = { + membershipRequestId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser!.id, + }; + + await cancelMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(MEMBERSHIP_REQUEST_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === membershipRequest.organzation + for membershipRequest with _id === args.membershipRequestId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + organization: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationCancelMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser!.id, + }; + + await cancelMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + organization: testOrganization!._id, + }, + } + ); + + const args: MutationCancelMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await cancelMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not the creator + of membershipRequest with _id === args.membershipRequest`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + user: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationCancelMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser!.id, + }; + + await cancelMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`deletes membershipRequest and returns it`, async () => { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + user: testUser!._id, + }, + } + ); + + const args: MutationCancelMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser!.id, + }; + + const cancelMembershipRequestPayload = + await cancelMembershipRequestResolver?.({}, args, context); + + expect(cancelMembershipRequestPayload).toEqual( + testMembershipRequest.toObject() + ); + + const testUpdatedUser = await User.findOne({ + _id: testUser!._id, + }) + .select(["membershipRequests"]) + .lean(); + + expect(testUpdatedUser?.membershipRequests).toEqual([]); + + const testUpdatedOrganization = await Organization.findOne({ + _id: testOrganization!._id, + }) + .select(["membershipRequests"]) + .lean(); + + expect(testUpdatedOrganization?.membershipRequests).toEqual([]); + }); +}); diff --git a/__tests__/resolvers/Mutation/createAdmin.spec.ts b/__tests__/resolvers/Mutation/createAdmin.spec.ts new file mode 100644 index 0000000000..c53b4d863d --- /dev/null +++ b/__tests__/resolvers/Mutation/createAdmin.spec.ts @@ -0,0 +1,235 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationCreateAdminArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createAdmin as createAdminResolver } from "../../../src/lib/resolvers/Mutation/createAdmin"; +import { + ORGANIZATION_MEMBER_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createAdmin", () => { + it(`throws NotFoundError if no organization exists with _id === args.data.organizationId`, async () => { + try { + const args: MutationCreateAdminArgs = { + data: { + organizationId: Types.ObjectId().toString(), + userId: "", + }, + }; + + const context = { + userId: testUser.id, + }; + + await createAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not the creator + of organization with _id === args.data.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + creator: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationCreateAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: testUser.id, + }, + }; + + const context = { + userId: testUser.id, + }; + + await createAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.data.userId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + creator: testUser._id, + }, + } + ); + + const args: MutationCreateAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: Types.ObjectId().toString(), + }, + }; + + const context = { + userId: testUser.id, + }; + + await createAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if user with _id === args.data.userId is not a member + of organzation with _id === args.data.organizationId`, async () => { + try { + const args: MutationCreateAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: testUser.id, + }, + }; + + const context = { + userId: testUser.id, + }; + + await createAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_MEMBER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === args.data.userId is already an admin + of organzation with _id === args.data.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + members: testUser._id, + }, + } + ); + + const args: MutationCreateAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: testUser.id, + }, + }; + + const context = { + userId: testUser.id, + }; + + await createAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`creates the admin and returns admin's user object`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationCreateAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: testUser.id, + }, + }; + + const context = { + userId: testUser.id, + }; + + const createAdminPayload = await createAdminResolver?.({}, args, context); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["-password"]) + .lean(); + + expect(createAdminPayload).toEqual(updatedTestUser); + + const updatedTestOrganization = await Organization.findOne({ + _id: testOrganization._id, + }) + .select(["admins"]) + .lean(); + + expect(updatedTestOrganization!.admins).toEqual([testUser._id]); + }); +}); diff --git a/__tests__/resolvers/Mutation/createComment.spec.ts b/__tests__/resolvers/Mutation/createComment.spec.ts new file mode 100644 index 0000000000..ca2e0b9b1d --- /dev/null +++ b/__tests__/resolvers/Mutation/createComment.spec.ts @@ -0,0 +1,122 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + Interface_Post, + Post, +} from "../../../src/lib/models"; +import { MutationCreateCommentArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createComment as createCommentResolver } from "../../../src/lib/resolvers/Mutation/createComment"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testPost: (Interface_Post & Document) | null; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createComment", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationCreateCommentArgs = { + data: { + text: "", + }, + postId: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await createCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`creates the comment and returns it`, async () => { + const args: MutationCreateCommentArgs = { + data: { + text: "text", + }, + postId: testPost!.id, + }; + + const context = { + userId: testUser.id, + }; + + const createCommentPayload = await createCommentResolver?.( + {}, + args, + context + ); + + expect(createCommentPayload).toEqual( + expect.objectContaining({ + text: "text", + creator: testUser._id, + post: testPost!._id, + }) + ); + + const testUpdatedPost = await Post.findOne({ + _id: testPost!._id, + }) + .select(["comments", "commentCount"]) + .lean(); + + expect(testUpdatedPost!.comments).toEqual([createCommentPayload?._id]); + expect(testUpdatedPost!.commentCount).toEqual(1); + }); +}); diff --git a/__tests__/resolvers/Mutation/createDirectChat.spec.ts b/__tests__/resolvers/Mutation/createDirectChat.spec.ts new file mode 100644 index 0000000000..c216f44128 --- /dev/null +++ b/__tests__/resolvers/Mutation/createDirectChat.spec.ts @@ -0,0 +1,142 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationCreateDirectChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createDirectChat as createDirectChatResolver } from "../../../src/lib/resolvers/Mutation/createDirectChat"; +import { ORGANIZATION_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createDirectChat", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationCreateDirectChatArgs = { + data: { + organizationId: "", + userIds: [], + }, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await createDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.data.organizationId`, async () => { + try { + const args: MutationCreateDirectChatArgs = { + data: { + organizationId: Types.ObjectId().toString(), + userIds: [], + }, + }; + + const context = { + userId: testUser.id, + }; + + await createDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists for any one of the ids in args.data.userIds`, async () => { + try { + const args: MutationCreateDirectChatArgs = { + data: { + organizationId: testOrganization.id, + userIds: [Types.ObjectId().toString()], + }, + }; + + const context = { + userId: testUser.id, + }; + + await createDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`creates the directChat and returns it`, async () => { + const args: MutationCreateDirectChatArgs = { + data: { + organizationId: testOrganization.id, + userIds: [testUser.id], + }, + }; + + const context = { + userId: testUser.id, + }; + + const createDirectChatPayload = await createDirectChatResolver?.( + {}, + args, + context + ); + + expect(createDirectChatPayload).toEqual( + expect.objectContaining({ + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createDonation.spec.ts b/__tests__/resolvers/Mutation/createDonation.spec.ts new file mode 100644 index 0000000000..ae19f42731 --- /dev/null +++ b/__tests__/resolvers/Mutation/createDonation.spec.ts @@ -0,0 +1,81 @@ +import "dotenv/config"; +import { Document } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationCreateDonationArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createDonation as createDonationResolver } from "../../../src/lib/resolvers/Mutation/createDonation"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createDonation", () => { + it(`creates the donation and returns it`, async () => { + const args: MutationCreateDonationArgs = { + amount: 1, + nameOfOrg: testOrganization.name, + nameOfUser: `${testUser.firstName} ${testUser.lastName}`, + orgId: testOrganization._id, + payPalId: "payPalId", + userId: testUser._id, + }; + + const createDonationPayload = await createDonationResolver?.({}, args, {}); + + expect(createDonationPayload).toEqual( + expect.objectContaining({ + amount: 1, + nameOfOrg: testOrganization.name, + nameOfUser: `${testUser.firstName} ${testUser.lastName}`, + orgId: testOrganization._id, + payPalId: "payPalId", + userId: testUser._id, + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createEvent.spec.ts b/__tests__/resolvers/Mutation/createEvent.spec.ts new file mode 100644 index 0000000000..789580e5eb --- /dev/null +++ b/__tests__/resolvers/Mutation/createEvent.spec.ts @@ -0,0 +1,220 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { + MutationCreateEventArgs, + Recurrance, +} from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createEvent as createEventResolver } from "../../../src/lib/resolvers/Mutation/createEvent"; +import { + ORGANIZATION_NOT_AUTHORIZED, + ORGANIZATION_NOT_FOUND, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + adminFor: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createEvent", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationCreateEventArgs = {}; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await createEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.data.organizationId`, async () => { + try { + const args: MutationCreateEventArgs = { + data: { + organizationId: Types.ObjectId().toString(), + allDay: false, + description: "", + endDate: "", + endTime: "", + isPublic: false, + isRegisterable: false, + latitude: 1, + longitude: 1, + location: "", + recurring: false, + startDate: "", + startTime: "", + title: "", + recurrance: Recurrance.Daily, + }, + }; + + const context = { + userId: testUser.id, + }; + + await createEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is neither the creator + nor a member of the organization with _id === args.organizationId`, async () => { + try { + const args: MutationCreateEventArgs = { + data: { + organizationId: testOrganization.id, + allDay: false, + description: "", + endDate: "", + endTime: "", + isPublic: false, + isRegisterable: false, + latitude: 1, + longitude: 1, + location: "", + recurring: false, + startDate: "", + startTime: "", + title: "", + recurrance: Recurrance.Daily, + }, + }; + + const context = { + userId: testUser.id, + }; + + await createEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_AUTHORIZED); + } + }); + + it(`creates the event and returns it`, async () => { + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + const args: MutationCreateEventArgs = { + data: { + organizationId: testOrganization.id, + allDay: false, + description: "newDescription", + endDate: new Date().toUTCString(), + endTime: new Date().toUTCString(), + isPublic: false, + isRegisterable: false, + latitude: 1, + longitude: 1, + location: "newLocation", + recurring: false, + startDate: new Date().toUTCString(), + startTime: new Date().toUTCString(), + title: "newTitle", + recurrance: Recurrance.Daily, + }, + }; + + const context = { + userId: testUser.id, + }; + + const createEventPayload = await createEventResolver?.({}, args, context); + + expect(createEventPayload).toEqual( + expect.objectContaining({ + allDay: false, + description: "newDescription", + isPublic: false, + isRegisterable: false, + latitude: 1, + longitude: 1, + location: "newLocation", + recurring: false, + title: "newTitle", + recurrance: Recurrance.Daily, + creator: testUser._id, + registrants: expect.arrayContaining([ + expect.objectContaining({ + userId: testUser._id.toString(), + user: testUser._id, + }), + ]), + admins: expect.arrayContaining([testUser._id]), + organization: testOrganization._id, + }) + ); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["eventAdmin", "createdEvents", "registeredEvents"]) + .lean(); + + expect(updatedTestUser).toEqual( + expect.objectContaining({ + eventAdmin: expect.arrayContaining([createEventPayload!._id]), + createdEvents: expect.arrayContaining([createEventPayload!._id]), + registeredEvents: expect.arrayContaining([createEventPayload!._id]), + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createGroupChat.spec.ts b/__tests__/resolvers/Mutation/createGroupChat.spec.ts new file mode 100644 index 0000000000..758623dfce --- /dev/null +++ b/__tests__/resolvers/Mutation/createGroupChat.spec.ts @@ -0,0 +1,147 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationCreateGroupChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createGroupChat as createGroupChatResolver } from "../../../src/lib/resolvers/Mutation/createGroupChat"; +import { ORGANIZATION_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createGroupChat", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationCreateGroupChatArgs = { + data: { + organizationId: "", + title: "", + userIds: [], + }, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await createGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.data.organizationId`, async () => { + try { + const args: MutationCreateGroupChatArgs = { + data: { + organizationId: Types.ObjectId().toString(), + title: "", + userIds: [], + }, + }; + + const context = { + userId: testUser.id, + }; + + await createGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists for any one of the ids in args.data.userIds`, async () => { + try { + const args: MutationCreateGroupChatArgs = { + data: { + organizationId: testOrganization.id, + title: "", + userIds: [Types.ObjectId().toString()], + }, + }; + + const context = { + userId: testUser.id, + }; + + await createGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`creates the groupChat and returns it`, async () => { + const args: MutationCreateGroupChatArgs = { + data: { + organizationId: testOrganization.id, + title: "title", + userIds: [testUser.id], + }, + }; + + const context = { + userId: testUser.id, + }; + + const createGroupChatPayload = await createGroupChatResolver?.( + {}, + args, + context + ); + + expect(createGroupChatPayload).toEqual( + expect.objectContaining({ + title: "title", + creator: testUser._id, + users: [testUser._id], + organization: testOrganization._id, + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createMessageChat.spec.ts b/__tests__/resolvers/Mutation/createMessageChat.spec.ts new file mode 100644 index 0000000000..6d0783cf20 --- /dev/null +++ b/__tests__/resolvers/Mutation/createMessageChat.spec.ts @@ -0,0 +1,101 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Interface_MessageChat, +} from "../../../src/lib/models"; +import { MutationCreateMessageChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createMessageChat as createMessageChatResolver } from "../../../src/lib/resolvers/Mutation/createMessageChat"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createMessageChat", () => { + it(`throws NotFoundError if no user exists with _id === args.data.receiver`, async () => { + try { + const args: MutationCreateMessageChatArgs = { + data: { + message: "", + receiver: Types.ObjectId().toString(), + }, + }; + + const context = { + userId: testUsers[0].id, + }; + + await createMessageChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`creates the organization and returns it`, async () => { + const args: MutationCreateMessageChatArgs = { + data: { + message: "message", + receiver: testUsers[1].id, + }, + }; + + const pubsub = { + publish: ( + _action: "CHAT_CHANNEL", + _payload: { + directMessageChat: Interface_MessageChat; + } + ) => { + return; + }, + }; + + const context = { + userId: testUsers[0].id, + pubsub, + }; + + const createMessageChatPayload = await createMessageChatResolver?.( + {}, + args, + context + ); + + expect(createMessageChatPayload).toEqual( + expect.objectContaining({ + sender: testUsers[0]._id, + receiver: testUsers[1]._id, + message: "message", + languageBarrier: false, + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createOrganization.spec.ts b/__tests__/resolvers/Mutation/createOrganization.spec.ts new file mode 100644 index 0000000000..6054db8d53 --- /dev/null +++ b/__tests__/resolvers/Mutation/createOrganization.spec.ts @@ -0,0 +1,103 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationCreateOrganizationArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createOrganization as createOrganizationResolver } from "../../../src/lib/resolvers/Mutation/createOrganization"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createOrganization", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationCreateOrganizationArgs = { + data: { + description: "description", + isPublic: true, + name: "name", + visibleInSearch: true, + apiUrl: "apiUrl", + location: "location", + }, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await createOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`creates the organization and returns it`, async () => { + const args: MutationCreateOrganizationArgs = { + data: { + description: "description", + isPublic: true, + name: "name", + visibleInSearch: true, + apiUrl: "apiUrl", + location: "location", + }, + }; + + const context = { + userId: testUser._id, + }; + + const createOrganizationPayload = await createOrganizationResolver?.( + {}, + args, + context + ); + + expect(createOrganizationPayload).toEqual( + expect.objectContaining({ + description: "description", + isPublic: true, + name: "name", + visibleInSearch: true, + apiUrl: "apiUrl", + location: "location", + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }) + ); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["joinedOrganizations", "createdOrganizations", "adminFor"]) + .lean(); + + expect(updatedTestUser).toEqual( + expect.objectContaining({ + joinedOrganizations: [createOrganizationPayload!._id], + createdOrganizations: [createOrganizationPayload!._id], + adminFor: [createOrganizationPayload!._id], + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createPlugin.spec.ts b/__tests__/resolvers/Mutation/createPlugin.spec.ts new file mode 100644 index 0000000000..2fbf1eecef --- /dev/null +++ b/__tests__/resolvers/Mutation/createPlugin.spec.ts @@ -0,0 +1,54 @@ +import "dotenv/config"; +import { Document } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationCreatePluginArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createPlugin as createPluginResolver } from "../../../src/lib/resolvers/Mutation/createPlugin"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createPlugin", () => { + it(`creates the plugin and returns it`, async () => { + const args: MutationCreatePluginArgs = { + pluginCreatedBy: `pluginCreatedBy`, + pluginDesc: "pluginDesc", + pluginInstallStatus: true, + pluginName: "pluginName", + installedOrgs: [], + }; + + const context = { + userId: testUser.id, + }; + + const createPluginPayload = await createPluginResolver?.({}, args, context); + + expect(createPluginPayload).toEqual( + expect.objectContaining({ + pluginCreatedBy: `pluginCreatedBy`, + pluginDesc: "pluginDesc", + pluginInstallStatus: true, + pluginName: "pluginName", + installedOrgs: [], + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createPost.spec.ts b/__tests__/resolvers/Mutation/createPost.spec.ts new file mode 100644 index 0000000000..2a18782e20 --- /dev/null +++ b/__tests__/resolvers/Mutation/createPost.spec.ts @@ -0,0 +1,127 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationCreatePostArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createPost as createPostResolver } from "../../../src/lib/resolvers/Mutation/createPost"; +import { ORGANIZATION_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createPost", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationCreatePostArgs = { + data: { + organizationId: "", + text: "", + videoUrl: "", + title: "", + }, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await createPostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.data.organizationId`, async () => { + try { + const args: MutationCreatePostArgs = { + data: { + organizationId: Types.ObjectId().toString(), + text: "", + videoUrl: "", + title: "", + }, + }; + + const context = { + userId: testUser.id, + }; + + await createPostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`creates the post and returns it`, async () => { + const args: MutationCreatePostArgs = { + data: { + organizationId: testOrganization.id, + text: "text", + videoUrl: "videoUrl", + title: "title", + }, + }; + + const context = { + userId: testUser.id, + }; + + const createPostPayload = await createPostResolver?.({}, args, context); + + expect(createPostPayload).toEqual( + expect.objectContaining({ + title: "title", + videoUrl: "videoUrl", + creator: testUser._id, + organization: testOrganization._id, + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/createTask.spec.ts b/__tests__/resolvers/Mutation/createTask.spec.ts new file mode 100644 index 0000000000..7e31da1ac4 --- /dev/null +++ b/__tests__/resolvers/Mutation/createTask.spec.ts @@ -0,0 +1,154 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Event, + Interface_Event, +} from "../../../src/lib/models"; +import { MutationCreateTaskArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { createTask as createTaskResolver } from "../../../src/lib/resolvers/Mutation/createTask"; +import { EVENT_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testEvent = await Event.create({ + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + eventAdmin: [testEvent._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> createTask", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationCreateTaskArgs = { + eventId: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await createTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no event exists with _id === args.eventId`, async () => { + try { + const args: MutationCreateTaskArgs = { + eventId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await createTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`creates the task and returns it`, async () => { + const args: MutationCreateTaskArgs = { + eventId: testEvent.id, + data: { + title: "title", + deadline: new Date().toString(), + description: "description", + }, + }; + + const context = { + userId: testUser._id, + }; + + const createTaskPayload = await createTaskResolver?.({}, args, context); + + expect(createTaskPayload).toEqual( + expect.objectContaining({ + title: "title", + description: "description", + }) + ); + expect(createTaskPayload?.deadline).toBeInstanceOf(Date); + + const testUpdatedEvent = await Event.findOne({ + _id: testEvent._id, + }) + .select(["tasks"]) + .lean(); + + expect(testUpdatedEvent!.tasks).toEqual([createTaskPayload?._id]); + }); +}); diff --git a/__tests__/resolvers/Mutation/deleteDonationById.spec.ts b/__tests__/resolvers/Mutation/deleteDonationById.spec.ts new file mode 100644 index 0000000000..e34b910807 --- /dev/null +++ b/__tests__/resolvers/Mutation/deleteDonationById.spec.ts @@ -0,0 +1,96 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + User, + Organization, + Interface_Donation, + Donation, +} from "../../../src/lib/models"; +import { MutationDeleteDonationByIdArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { deleteDonationById as deleteDonationByIdResolver } from "../../../src/lib/resolvers/Mutation/deleteDonationById"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDonation: Interface_Donation & Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testDonation = await Donation.create({ + amount: 1, + nameOfOrg: testOrganization.name, + nameOfUser: `${testUser.firstName} ${testUser.lastName}`, + orgId: testOrganization._id, + payPalId: "payPalId", + userId: testUser._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> deleteDonationById", () => { + it(`returns false if deletion of donation was unsuccessful`, async () => { + const args: MutationDeleteDonationByIdArgs = { + id: Types.ObjectId().toString(), + }; + + const deleteDonationByIdPayload = await deleteDonationByIdResolver?.( + {}, + args, + {} + ); + + expect(deleteDonationByIdPayload).toEqual({ + success: false, + }); + }); + + it(`returns true if deletion of donation was successful`, async () => { + const args: MutationDeleteDonationByIdArgs = { + id: testDonation._id, + }; + + const deleteDonationByIdPayload = await deleteDonationByIdResolver?.( + {}, + args, + {} + ); + + expect(deleteDonationByIdPayload).toEqual({ + success: true, + }); + }); +}); diff --git a/__tests__/resolvers/Mutation/forgotPassword.spec.ts b/__tests__/resolvers/Mutation/forgotPassword.spec.ts new file mode 100644 index 0000000000..5d530590cb --- /dev/null +++ b/__tests__/resolvers/Mutation/forgotPassword.spec.ts @@ -0,0 +1,95 @@ +import "dotenv/config"; +import { Document } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationForgotPasswordArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { forgotPassword as forgotPasswordResolver } from "../../../src/lib/resolvers/Mutation/forgotPassword"; +import { INVALID_OTP } from "../../../src/constants"; +import jwt from "jsonwebtoken"; +import { nanoid } from "nanoid"; +import bcrypt from "bcryptjs"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> forgotPassword", () => { + it(`throws Error if args.otp is incorrect`, async () => { + try { + const otpToken = jwt.sign( + { + email: testUser.email, + otp: "otp", + }, + process.env.NODE_ENV!, + { + expiresIn: 99999999, + } + ); + + const args: MutationForgotPasswordArgs = { + data: { + newPassword: "newPassword", + otpToken, + userOtp: "wrongOtp", + }, + }; + + await forgotPasswordResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(INVALID_OTP); + } + }); + + it(`changes the password if args.otp is correct`, async () => { + const otp = "otp"; + + const hashedOtp = await bcrypt.hash(otp, 1); + + const otpToken = jwt.sign( + { + email: testUser.email, + otp: hashedOtp, + }, + process.env.NODE_ENV!, + { + expiresIn: 99999999, + } + ); + + const args: MutationForgotPasswordArgs = { + data: { + newPassword: "newPassword", + otpToken, + userOtp: otp, + }, + }; + + const forgotPasswordPayload = await forgotPasswordResolver?.({}, args, {}); + + expect(forgotPasswordPayload).toEqual(true); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["password"]) + .lean(); + + expect(updatedTestUser?.password).not.toEqual(testUser.password); + }); +}); diff --git a/__tests__/resolvers/Mutation/joinPublicOrganization.spec.ts b/__tests__/resolvers/Mutation/joinPublicOrganization.spec.ts new file mode 100644 index 0000000000..8172be2d61 --- /dev/null +++ b/__tests__/resolvers/Mutation/joinPublicOrganization.spec.ts @@ -0,0 +1,180 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationJoinPublicOrganizationArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { joinPublicOrganization as joinPublicOrganizationResolver } from "../../../src/lib/resolvers/Mutation/joinPublicOrganization"; +import { + ORGANIZATION_NOT_FOUND, + USER_ALREADY_MEMBER, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: false, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: false, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> joinPublicOrganization", () => { + it(`throws NotFoundError if no organization exists with _id === args.organizationId`, async () => { + try { + const args: MutationJoinPublicOrganizationArgs = { + organizationId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await joinPublicOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if organization with _id === args.organizationId is not public`, async () => { + try { + const args: MutationJoinPublicOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await joinPublicOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + isPublic: true, + }, + } + ); + + const args: MutationJoinPublicOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await joinPublicOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws ConflictError if user with _id === context.userId is already a member + of organization with _id === args.organizationId`, async () => { + try { + const args: MutationJoinPublicOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await joinPublicOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_ALREADY_MEMBER); + } + }); + + it(`returns user object with _id === context.userId after joining the organization `, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + members: [], + }, + } + ); + + const args: MutationJoinPublicOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + const joinPublicOrganizationPayload = + await joinPublicOrganizationResolver?.({}, args, context); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["-password"]) + .lean(); + + expect(joinPublicOrganizationPayload).toEqual(updatedTestUser); + + const updatedTestOrganization = await Organization.findOne({ + _id: testOrganization._id, + }) + .select(["members"]) + .lean(); + + expect(updatedTestOrganization!.members).toEqual([testUser._id]); + }); +}); diff --git a/__tests__/resolvers/Mutation/leaveOrganization.spec.ts b/__tests__/resolvers/Mutation/leaveOrganization.spec.ts new file mode 100644 index 0000000000..4f36a44b73 --- /dev/null +++ b/__tests__/resolvers/Mutation/leaveOrganization.spec.ts @@ -0,0 +1,186 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationLeaveOrganizationArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { leaveOrganization as leaveOrganizationResolver } from "../../../src/lib/resolvers/Mutation/leaveOrganization"; +import { + MEMBER_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> leaveOrganization", () => { + it(`throws NotFoundError if no organization exists with _id === args.organizationId`, async () => { + try { + const args: MutationLeaveOrganizationArgs = { + organizationId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await leaveOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationLeaveOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await leaveOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is the creator + of organization with _id === args.organizationId`, async () => { + try { + const args: MutationLeaveOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await leaveOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws ConflictError if user with _id === context.userId is not a member + of organization with _id === args.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + creator: Types.ObjectId().toString(), + members: [], + }, + } + ); + + const args: MutationLeaveOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await leaveOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(MEMBER_NOT_FOUND); + } + }); + + it(`returns user object with _id === context.userId after leaving the organization`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + members: testUser._id, + }, + } + ); + + const args: MutationLeaveOrganizationArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + const leaveOrganizationPayload = await leaveOrganizationResolver?.( + {}, + args, + context + ); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["-password"]) + .lean(); + + expect(leaveOrganizationPayload).toEqual(updatedTestUser); + + const updatedTestOrganization = await Organization.findOne({ + _id: testOrganization._id, + }) + .select(["admins", "members"]) + .lean(); + + expect(updatedTestOrganization!.admins).toEqual([]); + expect(updatedTestOrganization!.members).toEqual([]); + }); +}); diff --git a/__tests__/resolvers/Mutation/likeComment.spec.ts b/__tests__/resolvers/Mutation/likeComment.spec.ts new file mode 100644 index 0000000000..bf619ccfdf --- /dev/null +++ b/__tests__/resolvers/Mutation/likeComment.spec.ts @@ -0,0 +1,150 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Post, + Comment, + Interface_Comment, +} from "../../../src/lib/models"; +import { MutationLikeCommentArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { likeComment as likeCommentResolver } from "../../../src/lib/resolvers/Mutation/likeComment"; +import { COMMENT_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testComment: Interface_Comment & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); + + testComment = await Comment.create({ + text: "text", + creator: testUser._id, + post: testPost._id, + }); + + await Post.updateOne( + { + _id: testPost._id, + }, + { + $push: { + comments: testComment._id, + }, + $inc: { + commentCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> likeComment", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationLikeCommentArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await likeCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no comment exists with _id === args.id`, async () => { + try { + const args: MutationLikeCommentArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await likeCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(COMMENT_NOT_FOUND); + } + }); + + it(`updates likedBy and likeCount fields on comment object with _id === args.id and + returns it `, async () => { + const args: MutationLikeCommentArgs = { + id: testComment.id, + }; + + const context = { + userId: testUser.id, + }; + + const likeCommentPayload = await likeCommentResolver?.({}, args, context); + + expect(likeCommentPayload?.likedBy).toEqual([testUser._id]); + expect(likeCommentPayload?.likeCount).toEqual(1); + }); + + it(`returns comment object with _id === args.id without liking the comment if user with + _id === context.userId has already liked it.`, async () => { + const args: MutationLikeCommentArgs = { + id: testComment.id, + }; + + const context = { + userId: testUser.id, + }; + + const likeCommentPayload = await likeCommentResolver?.({}, args, context); + + expect(likeCommentPayload?.likedBy).toEqual([testUser._id]); + expect(likeCommentPayload?.likeCount).toEqual(1); + }); +}); diff --git a/__tests__/resolvers/Mutation/likePost.spec.ts b/__tests__/resolvers/Mutation/likePost.spec.ts new file mode 100644 index 0000000000..bbeab0ac78 --- /dev/null +++ b/__tests__/resolvers/Mutation/likePost.spec.ts @@ -0,0 +1,129 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Post, + Interface_Post, +} from "../../../src/lib/models"; +import { MutationLikePostArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { likePost as likePostResolver } from "../../../src/lib/resolvers/Mutation/likePost"; +import { POST_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testPost: Interface_Post & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> likePost", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationLikePostArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await likePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no post exists with _id === args.id`, async () => { + try { + const args: MutationLikePostArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await likePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(POST_NOT_FOUND); + } + }); + + it(`updates likedBy and likeCount fields on post object with _id === args.id and + returns it `, async () => { + const args: MutationLikePostArgs = { + id: testPost.id, + }; + + const context = { + userId: testUser.id, + }; + + const likePostPayload = await likePostResolver?.({}, args, context); + + expect(likePostPayload?.likedBy).toEqual([testUser._id]); + expect(likePostPayload?.likeCount).toEqual(1); + }); + + it(`returns post object with _id === args.id without liking the post if user with + _id === context.userId has already liked it.`, async () => { + const args: MutationLikePostArgs = { + id: testPost.id, + }; + + const context = { + userId: testUser.id, + }; + + const likePostPayload = await likePostResolver?.({}, args, context); + + expect(likePostPayload?.likedBy).toEqual([testUser._id]); + expect(likePostPayload?.likeCount).toEqual(1); + }); +}); diff --git a/__tests__/resolvers/Mutation/login.spec.ts b/__tests__/resolvers/Mutation/login.spec.ts new file mode 100644 index 0000000000..7d49306df4 --- /dev/null +++ b/__tests__/resolvers/Mutation/login.spec.ts @@ -0,0 +1,196 @@ +import "dotenv/config"; +import { Document } from "mongoose"; +import { + Interface_User, + User, + Organization, + Event, + MembershipRequest, +} from "../../../src/lib/models"; +import { MutationLoginArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { login as loginResolver } from "../../../src/lib/resolvers/Mutation/login"; +import { + androidFirebaseOptions, + iosFirebaseOptions, +} from "../../../src/lib/config"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import bcrypt from "bcryptjs"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + const hashedTestPassword = await bcrypt.hash("password", 12); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: hashedTestPassword, + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testEvent = await Event.create({ + title: "title", + description: "decription", + recurring: false, + allDay: true, + startDate: new Date(), + isPublic: true, + isRegisterable: true, + creator: testUser._id, + registrants: [ + { + userId: testUser.id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + eventAdmin: testEvent._id, + createdEvents: testEvent._id, + registeredEvents: testEvent._id, + }, + } + ); + + const testMembershipRequest = await MembershipRequest.create({ + organization: testOrganization._id, + user: testUser._id, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + } + ); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> login", () => { + it(`throws NotFoundError if no user exists with email === args.data.email`, async () => { + try { + const args: MutationLoginArgs = { + data: { + email: `invalidEmail${nanoid().toLowerCase()}@gmail.com`, + password: "password", + }, + }; + + await loginResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws ValidationError if args.data.password !== password for user with + email === args.data.email`, async () => { + try { + const args: MutationLoginArgs = { + data: { + email: testUser.email, + password: "incorrectPassword", + }, + }; + + await loginResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual("Invalid credentials"); + } + }); + + it(`returns the user object with populated fields joinedOrganizations, createdOrganizations, + createdEvents, registeredEvents, eventAdmin, adminFor, membershipRequests, + organizationsBlockedBy, organizationUserBelongsTo`, async () => { + const args: MutationLoginArgs = { + data: { + email: testUser.email, + password: "password", + }, + }; + + const loginPayload = await loginResolver?.({}, args, {}); + + testUser = await User.findOne({ + _id: testUser._id, + }) + .select(["-password"]) + .populate("joinedOrganizations") + .populate("createdOrganizations") + .populate("createdEvents") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .populate("membershipRequests") + .populate("organizationsBlockedBy") + .populate("organizationUserBelongsTo") + .lean(); + + expect(loginPayload).toEqual( + expect.objectContaining({ + user: testUser, + androidFirebaseOptions, + iosFirebaseOptions, + }) + ); + expect(typeof loginPayload?.accessToken).toBe("string"); + expect(loginPayload?.accessToken.length).toBeGreaterThan(1); + + expect(typeof loginPayload?.refreshToken).toBe("string"); + expect(loginPayload?.refreshToken.length).toBeGreaterThan(1); + }); +}); diff --git a/__tests__/resolvers/Mutation/logout.spec.ts b/__tests__/resolvers/Mutation/logout.spec.ts new file mode 100644 index 0000000000..8cee8dc1bc --- /dev/null +++ b/__tests__/resolvers/Mutation/logout.spec.ts @@ -0,0 +1,87 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { logout as logoutResolver } from "../../../src/lib/resolvers/Mutation/logout"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> logout", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const context = { + userId: Types.ObjectId().toString(), + }; + + await logoutResolver?.({}, {}, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`sets token === null for user with _id === context.userId and returns true`, async () => { + const context = { + userId: testUser.id, + }; + + const logoutPayload = await logoutResolver?.({}, {}, context); + + expect(logoutPayload).toEqual(true); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["token"]) + .lean(); + + expect(updatedTestUser!.token).toEqual(null); + }); +}); diff --git a/__tests__/resolvers/Mutation/otp.spec.ts b/__tests__/resolvers/Mutation/otp.spec.ts new file mode 100644 index 0000000000..fab8b6e0d7 --- /dev/null +++ b/__tests__/resolvers/Mutation/otp.spec.ts @@ -0,0 +1,69 @@ +import "dotenv/config"; +import { MutationOtpArgs } from "../../../src/generated/graphqlCodegen"; +// import { Document } from "mongoose"; +// import { Interface_User, User } from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { otp as otpResolver } from "../../../src/lib/resolvers/Mutation/otp"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +// let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + // testUser = await User.create({ + // email: `email${nanoid().toLowerCase()}@gmail.com`, + // password: "password", + // firstName: "firstName", + // lastName: "lastName", + // appLanguageCode: "en", + // }); +}); + +afterAll(async () => { + await disconnect(); +}); + +// describe('Testing otp resolver', () => { +// test('otp', async () => { +// console.log(token); + +// const args = { +// data: { +// email: generatedEmail, +// }, +// }; + +// await expect(() => otp({}, args)).rejects.toEqual(ERROR_IN_SENDING_MAIL); +// }); + +// test('Testing, when user email is incorrect', async () => { +// const args = { +// data: { +// email: 'abc4321@email.com', +// }, +// }; + +// await expect(async () => { +// await otp({}, args); +// }).rejects.toEqual(Error(USER_NOT_FOUND)); +// }); +// }); + +describe("resolvers -> Mutation -> otp", () => { + it("throws Error if no user exists with email === args.data.email", async () => { + try { + const args: MutationOtpArgs = { + data: { + email: `email${nanoid().toLowerCase()}@gmail.com`, + }, + }; + + await otpResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); +}); diff --git a/__tests__/resolvers/Mutation/recaptcha.spec.ts b/__tests__/resolvers/Mutation/recaptcha.spec.ts new file mode 100644 index 0000000000..a5e15148f1 --- /dev/null +++ b/__tests__/resolvers/Mutation/recaptcha.spec.ts @@ -0,0 +1,17 @@ +import { MutationRecaptchaArgs } from "../../../src/generated/graphqlCodegen"; +import { recaptcha as recaptchaResolver } from "../../../src/lib/resolvers/Mutation/recaptcha"; +import { describe, it, expect } from "vitest"; + +describe("resolvers -> Mutation -> recaptcha", () => { + it("", async () => { + const args: MutationRecaptchaArgs = { + data: { + recaptchaToken: "dummyToken", + }, + }; + + const recaptchaPayload = await recaptchaResolver?.({}, args, {}); + + expect(recaptchaPayload).toBeFalsy(); + }); +}); diff --git a/__tests__/resolvers/Mutation/refreshToken.spec.ts b/__tests__/resolvers/Mutation/refreshToken.spec.ts new file mode 100644 index 0000000000..2141fb26cf --- /dev/null +++ b/__tests__/resolvers/Mutation/refreshToken.spec.ts @@ -0,0 +1,114 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationRefreshTokenArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { refreshToken as refreshTokenResolver } from "../../../src/lib/resolvers/Mutation/refreshToken"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { createRefreshToken } from "../../../src/lib/utilities"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let refreshToken: string; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> refreshToken", () => { + it(`throws NotFoundError if no refreshToken is provided using args.refreshToken`, async () => { + try { + const args: MutationRefreshTokenArgs = { + refreshToken: "", + }; + + await refreshTokenResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual("Invalid refreshToken"); + } + }); + + it(`throws NotFoundError if no user exists with _id === payload.userId for + args.refreshToken`, async () => { + try { + refreshToken = await createRefreshToken({ + ...testUser.toObject(), + _id: Types.ObjectId(), + }); + + const args: MutationRefreshTokenArgs = { + refreshToken, + }; + + await refreshTokenResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws ValidationError if user.tokenVersion !== payload.tokenVersion for user + with _id === payload.userId for args.refreshToken`, async () => { + try { + await User.updateOne( + { + _id: testUser._id, + }, + { + $inc: { + tokenVersion: 1, + }, + } + ); + + refreshToken = await createRefreshToken(testUser.toObject()); + + const args: MutationRefreshTokenArgs = { + refreshToken, + }; + + await refreshTokenResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual("Invalid refreshToken"); + } + }); + + it(`generates new accessToken and refreshToken and returns them`, async () => { + await User.updateOne( + { + _id: testUser._id, + }, + { + $inc: { + tokenVersion: -1, + }, + } + ); + + refreshToken = await createRefreshToken(testUser.toObject()); + + const args: MutationRefreshTokenArgs = { + refreshToken, + }; + + const refreshTokenPayload = await refreshTokenResolver?.({}, args, {}); + + expect(typeof refreshTokenPayload?.accessToken).toEqual("string"); + expect(refreshTokenPayload?.accessToken.length).toBeGreaterThan(1); + + expect(typeof refreshTokenPayload?.refreshToken).toEqual("string"); + expect(refreshTokenPayload?.refreshToken.length).toBeGreaterThan(1); + }); +}); diff --git a/__tests__/resolvers/Mutation/registerForEvent.spec.ts b/__tests__/resolvers/Mutation/registerForEvent.spec.ts new file mode 100644 index 0000000000..019a4b84ea --- /dev/null +++ b/__tests__/resolvers/Mutation/registerForEvent.spec.ts @@ -0,0 +1,235 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Event, + Interface_Event, +} from "../../../src/lib/models"; +import { MutationRegisterForEventArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { registerForEvent as registerForEventResolver } from "../../../src/lib/resolvers/Mutation/registerForEvent"; +import { + EVENT_NOT_FOUND, + REGISTRANT_ALREADY_EXIST, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testEvent = await Event.create({ + creator: testUser._id, + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + registrants: [ + { + userId: testUser.id, + user: testUser._id, + status: "ACTIVE", + }, + ], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdEvents: [testEvent._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> registerForEvent", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationRegisterForEventArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await registerForEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no event exists with _id === args.id`, async () => { + try { + const args: MutationRegisterForEventArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser._id, + }; + + await registerForEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`throws NotFoundError if user with _id === context.userId is already a + registrant of event with _id === args.id and event.registrant.status === "ACTIVE" + for the registrant with registrant.userId === context.userId + `, async () => { + try { + const args: MutationRegisterForEventArgs = { + id: testEvent._id, + }; + + const context = { + userId: testUser._id, + }; + + await registerForEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(REGISTRANT_ALREADY_EXIST); + } + }); + + it(`if user with _id === context.userId is already a registrant for event with _id === args.id + sets event.registrant.status field to "ACTIVE" for registrant with + _id === context.userId`, async () => { + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $set: { + registrants: [ + { + userId: testUser.id, + user: testUser._id, + status: "BLOCKED", + }, + ], + }, + } + ); + + const args: MutationRegisterForEventArgs = { + id: testEvent._id, + }; + + const context = { + userId: testUser._id, + }; + + const registerForEventPayload = await registerForEventResolver?.( + {}, + args, + context + ); + + const testRegisterForEventPayload = await Event.findOne({ + _id: testEvent._id, + }).lean(); + + expect(registerForEventPayload).toEqual(testRegisterForEventPayload); + }); + + it(`registers user with _id === context.userId as a registrant for event with + _id === args.id`, async () => { + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $set: { + registrants: [], + }, + } + ); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + registeredEvents: [], + }, + } + ); + + const args: MutationRegisterForEventArgs = { + id: testEvent._id, + }; + + const context = { + userId: testUser._id, + }; + + const registerForEventPayload = await registerForEventResolver?.( + {}, + args, + context + ); + + const testRegisterForEventPayload = await Event.findOne({ + _id: testEvent._id, + }).lean(); + + expect(registerForEventPayload).toEqual(testRegisterForEventPayload); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["registeredEvents"]) + .lean(); + + expect(updatedTestUser?.registeredEvents).toEqual([testEvent._id]); + }); +}); diff --git a/__tests__/resolvers/Mutation/rejectAdmin.spec.ts b/__tests__/resolvers/Mutation/rejectAdmin.spec.ts new file mode 100644 index 0000000000..8a61a8fc14 --- /dev/null +++ b/__tests__/resolvers/Mutation/rejectAdmin.spec.ts @@ -0,0 +1,108 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationRejectAdminArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { rejectAdmin as rejectAdminResolver } from "../../../src/lib/resolvers/Mutation/rejectAdmin"; +import { USER_NOT_AUTHORIZED, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> rejectAdmin", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationRejectAdminArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await rejectAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws Error if userType of user with _id === context.userId is not SUPERADMIN`, async () => { + try { + const args: MutationRejectAdminArgs = { + id: "", + }; + + const context = { + userId: testUser.id, + }; + + await rejectAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.id`, async () => { + try { + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + userType: "SUPERADMIN", + }, + } + ); + + const args: MutationRejectAdminArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await rejectAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`deletes the user with _id === args.id and returns true`, async () => { + const args: MutationRejectAdminArgs = { + id: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const rejectAdminPayload = await rejectAdminResolver?.({}, args, context); + + expect(rejectAdminPayload).toEqual(true); + + const deletedTestUser = await User.findOne({ + _id: testUser._id, + }).lean(); + + expect(deletedTestUser).toEqual(null); + }); +}); diff --git a/__tests__/resolvers/Mutation/rejectMembershipRequest.spec.ts b/__tests__/resolvers/Mutation/rejectMembershipRequest.spec.ts new file mode 100644 index 0000000000..d2ed28056c --- /dev/null +++ b/__tests__/resolvers/Mutation/rejectMembershipRequest.spec.ts @@ -0,0 +1,268 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + MembershipRequest, + Interface_MembershipRequest, +} from "../../../src/lib/models"; +import { MutationRejectMembershipRequestArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { rejectMembershipRequest as rejectMembershipRequestResolver } from "../../../src/lib/resolvers/Mutation/rejectMembershipRequest"; +import { + MEMBERSHIP_REQUEST_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: (Interface_User & Document) | null; +let testOrganization: + | (Interface_Organization & Document) + | null; +let testMembershipRequest: Interface_MembershipRequest & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testMembershipRequest = await MembershipRequest.create({ + user: testUser._id, + organization: testOrganization._id, + }); + + testUser = await User.findOneAndUpdate( + { + _id: testUser._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + }, + { + new: true, + } + ); + + testOrganization = await Organization.findOneAndUpdate( + { + _id: testOrganization._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + }, + { + new: true, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> rejectMembershipRequest", () => { + it(`throws NotFoundError if no membershipRequest exists with _id === args.membershipRequestId`, async () => { + try { + const args: MutationRejectMembershipRequestArgs = { + membershipRequestId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser!.id, + }; + + await rejectMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(MEMBERSHIP_REQUEST_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === membershipRequest.organzation + for membershipRequest with _id === args.membershipRequestId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + organization: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationRejectMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser!.id, + }; + + await rejectMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === membershipRequest.user + for membershipRequest with _id === args.membershipRequestId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + organization: testOrganization!._id, + }, + } + ); + + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + user: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationRejectMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser!.id, + }; + + await rejectMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not an admin + of organzation with _id === membershipRequest.organzation for membershipRequest + with _id === args.membershipRequestId`, async () => { + try { + await MembershipRequest.updateOne( + { + _id: testMembershipRequest._id, + }, + { + $set: { + user: testUser!._id, + }, + } + ); + + await Organization.updateOne( + { + _id: testOrganization!._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationRejectMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser!.id, + }; + + await rejectMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`deletes membershipRequest with _id === args.membershipRequestId`, async () => { + await Organization.updateOne( + { + _id: testOrganization!._id, + }, + { + $push: { + admins: testUser!._id, + }, + } + ); + + const args: MutationRejectMembershipRequestArgs = { + membershipRequestId: testMembershipRequest.id, + }; + + const context = { + userId: testUser!.id, + }; + + const rejectMembershipRequestPayload = + await rejectMembershipRequestResolver?.({}, args, context); + + expect(rejectMembershipRequestPayload).toEqual( + testMembershipRequest.toObject() + ); + + const testUpdatedUser = await User.findOne({ + _id: testUser!._id, + }) + .select(["membershipRequests"]) + .lean(); + + expect(testUpdatedUser?.membershipRequests).toEqual([]); + + const testUpdatedOrganization = await Organization.findOne({ + _id: testOrganization!._id, + }) + .select(["membershipRequests"]) + .lean(); + + expect(testUpdatedOrganization?.membershipRequests).toEqual([]); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeAdmin.spec.ts b/__tests__/resolvers/Mutation/removeAdmin.spec.ts new file mode 100644 index 0000000000..0d698dfa8f --- /dev/null +++ b/__tests__/resolvers/Mutation/removeAdmin.spec.ts @@ -0,0 +1,200 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationRemoveAdminArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeAdmin as removeAdminResolver } from "../../../src/lib/resolvers/Mutation/removeAdmin"; +import { + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeAdmin", () => { + it(`throws NotFoundError if no organization exists with _id === args.data.organizationId`, async () => { + try { + const args: MutationRemoveAdminArgs = { + data: { + organizationId: Types.ObjectId().toString(), + userId: "", + }, + }; + + const context = { + userId: testUser.id, + }; + + await removeAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.data.userId`, async () => { + try { + const args: MutationRemoveAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: Types.ObjectId().toString(), + }, + }; + + const context = { + userId: testUser.id, + }; + + await removeAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === args.data.userId is not an admin + of organzation with _id === args.data.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationRemoveAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: testUser.id, + }, + }; + + const context = { + userId: testUser.id, + }; + + await removeAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not the creator + of organization with _id === args.data.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + $set: { + creator: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationRemoveAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: testUser.id, + }, + }; + + const context = { + userId: testUser.id, + }; + + await removeAdminResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`removes user with _id === args.data.userId from admins list of the organization + with _id === args.data.organizationId`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + creator: testUser._id, + }, + } + ); + + const args: MutationRemoveAdminArgs = { + data: { + organizationId: testOrganization.id, + userId: testUser.id, + }, + }; + + const context = { + userId: testUser.id, + }; + + const removeAdminPayload = await removeAdminResolver?.({}, args, context); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["-password"]) + .lean(); + + expect(removeAdminPayload).toEqual(updatedTestUser); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeComment.spec.ts b/__tests__/resolvers/Mutation/removeComment.spec.ts new file mode 100644 index 0000000000..fea6057117 --- /dev/null +++ b/__tests__/resolvers/Mutation/removeComment.spec.ts @@ -0,0 +1,197 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + Comment, + Interface_Post, + Interface_Comment, + Post, +} from "../../../src/lib/models"; +import { MutationRemoveCommentArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeComment as removeCommentResolver } from "../../../src/lib/resolvers/Mutation/removeComment"; +import { + COMMENT_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testPost: (Interface_Post & Document) | null; +let testComment: + | (Interface_Comment & Document) + | null; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); + + testComment = await Comment.create({ + text: "text", + creator: testUser._id, + post: testPost._id, + }); + + testPost = await Post.findOneAndUpdate( + { + _id: testPost._id, + }, + { + $push: { + comments: testComment._id, + }, + $inc: { + commentCount: 1, + }, + }, + { + new: true, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeComment", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationRemoveCommentArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await removeCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no comment exists with _id === args.id`, async () => { + try { + const args: MutationRemoveCommentArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await removeCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(COMMENT_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not the creator + of comment with _id === args.id`, async () => { + try { + await Comment.updateOne( + { + _id: testComment!._id, + }, + { + $set: { + creator: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationRemoveCommentArgs = { + id: testComment!.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`deletes the comment with _id === args.id`, async () => { + await Comment.updateOne( + { + _id: testComment!._id, + }, + { + $set: { + creator: testUser._id, + }, + } + ); + + const args: MutationRemoveCommentArgs = { + id: testComment!.id, + }; + + const context = { + userId: testUser.id, + }; + + const removeCommentPayload = await removeCommentResolver?.( + {}, + args, + context + ); + + expect(removeCommentPayload).toEqual(testComment!.toObject()); + + const testUpdatedPost = await Post.findOne({ + _id: testPost!._id, + }) + .select(["comments", "commentCount"]) + .lean(); + + expect(testUpdatedPost!.comments).toEqual([]); + expect(testUpdatedPost!.commentCount).toEqual(0); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeDirectChat.spec.ts b/__tests__/resolvers/Mutation/removeDirectChat.spec.ts new file mode 100644 index 0000000000..827b56eea6 --- /dev/null +++ b/__tests__/resolvers/Mutation/removeDirectChat.spec.ts @@ -0,0 +1,195 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + Interface_DirectChat, + DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { MutationRemoveDirectChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeDirectChat as removeDirectChatResolver } from "../../../src/lib/resolvers/Mutation/removeDirectChat"; +import { + CHAT_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testDirectChat: + | (Interface_DirectChat & Document) + | null; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testDirectChat = await DirectChat.create({ + users: [testUser._id], + creator: testUser._id, + organization: testOrganization._id, + }); + + const testDirectChatMessage = await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUser._id, + receiver: testUser._id, + messageContent: "messageContent", + createdAt: new Date(), + }); + + testDirectChat = await DirectChat.findOneAndUpdate( + { + _id: testDirectChat._id, + }, + { + $push: { + messages: testDirectChatMessage._id, + }, + }, + { + new: true, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeDirectChat", () => { + it(`throws NotFoundError if no organization exists with _id === args.organizationId`, async () => { + try { + const args: MutationRemoveDirectChatArgs = { + chatId: "", + organizationId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await removeDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no directChat exists with _id === args.chatId`, async () => { + try { + const args: MutationRemoveDirectChatArgs = { + chatId: Types.ObjectId().toString(), + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not an admin + of organization with _id === args.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationRemoveDirectChatArgs = { + chatId: testDirectChat!.id, + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`deletes the directChat with _id === args.chatId`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationRemoveDirectChatArgs = { + chatId: testDirectChat!.id, + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + const removeDirectChatPayload = await removeDirectChatResolver?.( + {}, + args, + context + ); + + expect(removeDirectChatPayload).toEqual(testDirectChat?.toObject()); + + const testDeletedDirectChatMessages = await DirectChatMessage.find({ + directChatMessageBelongsTo: testDirectChat!._id, + }).lean(); + + expect(testDeletedDirectChatMessages).toEqual([]); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeEvent.spec.ts b/__tests__/resolvers/Mutation/removeEvent.spec.ts new file mode 100644 index 0000000000..93dfb98038 --- /dev/null +++ b/__tests__/resolvers/Mutation/removeEvent.spec.ts @@ -0,0 +1,217 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + Interface_Event, + Event, +} from "../../../src/lib/models"; +import { MutationRemoveEventArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeEvent as removeEventResolver } from "../../../src/lib/resolvers/Mutation/removeEvent"; +import { + EVENT_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testEvent: (Interface_Event & Document) | null; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testEvent = await Event.create({ + title: "title", + description: "description", + allDay: true, + startDate: new Date(), + recurring: true, + isPublic: true, + isRegisterable: true, + creator: testUser._id, + admins: [testUser._id], + registrants: [], + organization: testOrganization._id, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + eventAdmin: testEvent._id, + createdEvents: testEvent._id, + registeredEvents: testEvent._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeEvent", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationRemoveEventArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await removeEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no event exists with _id === args.id`, async () => { + try { + const args: MutationRemoveEventArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await removeEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is neither an + admin of organization with _id === event.organization for event with _id === args.id + or an admin for event with _id === args.id`, async () => { + try { + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + adminFor: [], + }, + } + ); + + await Event.updateOne( + { + _id: testEvent!._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationRemoveEventArgs = { + id: testEvent!.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`removes event with _id === args.id and returns it`, async () => { + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + adminFor: testOrganization._id, + }, + } + ); + + await Event.updateOne( + { + _id: testEvent!._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationRemoveEventArgs = { + id: testEvent!.id, + }; + + const context = { + userId: testUser.id, + }; + + const removeEventPayload = await removeEventResolver?.({}, args, context); + + expect(removeEventPayload).toEqual(testEvent!.toObject()); + + const updatedTestUser = await User.findOne({ + _id: testUser._id, + }) + .select(["createdEvents", "eventAdmin"]) + .lean(); + + expect(updatedTestUser!.createdEvents).toEqual([]); + expect(updatedTestUser!.eventAdmin).toEqual([]); + + const updatedTestEvent = await Event.findOne({ + _id: testEvent!._id, + }) + .select(["status"]) + .lean(); + + expect(updatedTestEvent!.status).toEqual("DELETED"); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeGroupChat.spec.ts b/__tests__/resolvers/Mutation/removeGroupChat.spec.ts new file mode 100644 index 0000000000..ccfe4b2519 --- /dev/null +++ b/__tests__/resolvers/Mutation/removeGroupChat.spec.ts @@ -0,0 +1,216 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + GroupChat, + Interface_GroupChat, + GroupChatMessage, +} from "../../../src/lib/models"; +import { MutationRemoveGroupChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeGroupChat as removeGroupChatResolver } from "../../../src/lib/resolvers/Mutation/removeGroupChat"; +import { + CHAT_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testGroupChat: + | (Interface_GroupChat & Document) + | null; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testGroupChat = await GroupChat.create({ + title: "title", + users: [testUser._id], + creator: testUser._id, + organization: testOrganization._id, + }); + + const testGroupChatMessage = await GroupChatMessage.create({ + groupChatMessageBelongsTo: testGroupChat._id, + sender: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); + + testGroupChat = await GroupChat.findOneAndUpdate( + { + _id: testGroupChat._id, + }, + { + $push: { + messages: testGroupChatMessage._id, + }, + }, + { + new: true, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeGroupChat", () => { + it(`throws NotFoundError if no groupChat exists with _id === args.chatId`, async () => { + try { + const args: MutationRemoveGroupChatArgs = { + chatId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await removeGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === groupChat.organization + for field organization of groupChat with _id === args.chatId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat!._id, + }, + { + $set: { + organization: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationRemoveGroupChatArgs = { + chatId: testGroupChat!.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is + not an admin of organization with _id === groupChat.organization for groupChat + with _id === args.chatId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat!._id, + }, + { + $set: { + organization: testOrganization._id, + }, + } + ); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [], + }, + } + ); + + const args: MutationRemoveGroupChatArgs = { + chatId: testGroupChat!.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`deletes the groupChat with _id === args.chatId and all groupChatMessages + associated to it and returns it`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationRemoveGroupChatArgs = { + chatId: testGroupChat!.id, + }; + + const context = { + userId: testUser.id, + }; + + const removeGroupChatPayload = await removeGroupChatResolver?.( + {}, + args, + context + ); + + expect(removeGroupChatPayload).toEqual(testGroupChat!.toObject()); + + const testDeletedGroupChatMessages = await GroupChatMessage.find({ + groupChatMessageBelongsTo: testGroupChat!._id, + }).lean(); + + expect(testDeletedGroupChatMessages).toEqual([]); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeMember.spec.ts b/__tests__/resolvers/Mutation/removeMember.spec.ts new file mode 100644 index 0000000000..c8e7c8cd4d --- /dev/null +++ b/__tests__/resolvers/Mutation/removeMember.spec.ts @@ -0,0 +1,269 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationRemoveMemberArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeMember as removeMemberResolver } from "../../../src/lib/resolvers/Mutation/removeMember"; +import { + MEMBER_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[1]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id, testUsers[1]._id], + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + await User.updateOne( + { + _id: testUsers[1]._id, + }, + { + $push: { + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + await User.updateOne( + { + _id: testUsers[2]._id, + }, + { + $push: { + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeMember", () => { + it(`throws NotFoundError if no organization exists with _id === args.data.organizationId`, async () => { + try { + const args: MutationRemoveMemberArgs = { + data: { + organizationId: Types.ObjectId().toString(), + userIds: [], + }, + }; + + const context = { + userId: testUsers[0].id, + }; + + await removeMemberResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is + not an admin of the organization with _id === args.data.organizationId`, async () => { + try { + const args: MutationRemoveMemberArgs = { + data: { + organizationId: testOrganization.id, + userIds: [], + }, + }; + + const context = { + userId: testUsers[2].id, + }; + + await removeMemberResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws Error if no user exists for one of the ids in args.data.userIds`, async () => { + try { + const args: MutationRemoveMemberArgs = { + data: { + organizationId: testOrganization.id, + userIds: [Types.ObjectId().toString(), Types.ObjectId().toString()], + }, + }; + + const context = { + userId: testUsers[0].id, + }; + + await removeMemberResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws Error if user with one of the ids in args.data.userIds is not + a member of organization with _id === args.data.organizationId`, async () => { + try { + const args: MutationRemoveMemberArgs = { + data: { + organizationId: testOrganization.id, + userIds: [testUsers[2].id], + }, + }; + + const context = { + userId: testUsers[0].id, + }; + + await removeMemberResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(MEMBER_NOT_FOUND); + } + }); + + it(`throws Error if user with one of the ids in args.data.userIds is an admin + of organization with _id === args.data.organizationId`, async () => { + try { + const args: MutationRemoveMemberArgs = { + data: { + organizationId: testOrganization.id, + userIds: [testUsers[0].id], + }, + }; + + const context = { + userId: testUsers[0].id, + }; + + await removeMemberResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual( + "Administrators cannot remove members who are also Administrators" + ); + } + }); + + it(`throws Error if user with one of the ids in args.data.userIds is the creator + of organization with _id === args.data.organizationId`, async () => { + try { + const args: MutationRemoveMemberArgs = { + data: { + organizationId: testOrganization.id, + userIds: [testUsers[1].id], + }, + }; + + const context = { + userId: testUsers[0].id, + }; + + await removeMemberResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual( + "Administrators cannot remove the creator of the organization from the organization" + ); + } + }); + + it(`removes the the users with ids === args.data.userIds from members list of + organization with _id === args.data.organizationId and returns the updated organization`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + creator: testUsers[0]._id, + }, + } + ); + + const args: MutationRemoveMemberArgs = { + data: { + organizationId: testOrganization.id, + userIds: [testUsers[1].id], + }, + }; + + const context = { + userId: testUsers[0].id, + }; + + const removeMemberPayload = await removeMemberResolver?.({}, args, context); + + const testRemoveMemberPayload = await Organization.findOne({ + _id: testOrganization._id, + }).lean(); + + expect(removeMemberPayload).toEqual(testRemoveMemberPayload); + + const testUpdatedUser = await User.findOne({ + _id: testUsers[1]._id, + }) + .select("joinedOrganizations") + .lean(); + + expect(testUpdatedUser).toEqual( + expect.objectContaining({ + joinedOrganizations: [], + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeOrganization.spec.ts b/__tests__/resolvers/Mutation/removeOrganization.spec.ts new file mode 100644 index 0000000000..428f61f842 --- /dev/null +++ b/__tests__/resolvers/Mutation/removeOrganization.spec.ts @@ -0,0 +1,263 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + Post, + Comment, + MembershipRequest, + Interface_Comment, + Interface_Post, +} from "../../../src/lib/models"; +import { MutationRemoveOrganizationArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeOrganization as removeOrganizationResolver } from "../../../src/lib/resolvers/Mutation/removeOrganization"; +import { + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; +let testOrganization: Interface_Organization & + Document; +let testPost: Interface_Post & Document; +let testComment: Interface_Comment & Document; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[1]._id], + blockedUsers: [testUsers[0]._id], + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + organizationsBlockedBy: [testOrganization._id], + }, + } + ); + + await User.updateOne( + { + _id: testUsers[1]._id, + }, + { + $set: { + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testMembershipRequest = await MembershipRequest.create({ + organization: testOrganization._id, + user: testUsers[0]._id, + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUsers[0]._id, + organization: testOrganization._id, + }); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + posts: testPost._id, + }, + } + ); + + testComment = await Comment.create({ + text: "text", + creator: testUsers[0]._id, + post: testPost._id, + }); + + await Post.updateOne( + { + _id: testPost._id, + }, + { + $push: { + comments: testComment._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeOrganization", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationRemoveOrganizationArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await removeOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.id`, async () => { + try { + const args: MutationRemoveOrganizationArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUsers[0].id, + }; + + await removeOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId + is not the creator of organization with _id === args.id`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + creator: Types.ObjectId().toString(), + }, + } + ); + + const args: MutationRemoveOrganizationArgs = { + id: testOrganization.id, + }; + + const context = { + userId: testUsers[0].id, + }; + + await removeOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`removes the organization and returns the updated user's object with _id === context.userId`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + creator: testUsers[0]._id, + }, + } + ); + + const args: MutationRemoveOrganizationArgs = { + id: testOrganization._id, + }; + + const context = { + userId: testUsers[0]._id, + }; + + const removeOrganizationPayload = await removeOrganizationResolver?.( + {}, + args, + context + ); + + const updatedTestUser = await User.findOne({ + _id: testUsers[0]._id, + }) + .select(["-password"]) + .lean(); + + expect(removeOrganizationPayload).toEqual(updatedTestUser); + + const updatedTestUser1 = await User.findOne({ + _id: testUsers[1]._id, + }) + .select(["joinedOrganizations"]) + .lean(); + + expect(updatedTestUser1?.joinedOrganizations).toEqual([]); + + const deletedMembershipRequests = await MembershipRequest.find({ + organization: testOrganization._id, + }).lean(); + + const deletedTestPosts = await Post.find({ + _id: testPost._id, + }).lean(); + + const deletedTestComments = await Comment.find({ + _id: testComment._id, + }).lean(); + + expect(deletedMembershipRequests).toEqual([]); + + expect(deletedTestPosts).toEqual([]); + + expect(deletedTestComments).toEqual([]); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeOrganizationImage.spec.ts b/__tests__/resolvers/Mutation/removeOrganizationImage.spec.ts new file mode 100644 index 0000000000..fee164e8dc --- /dev/null +++ b/__tests__/resolvers/Mutation/removeOrganizationImage.spec.ts @@ -0,0 +1,172 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationRemoveOrganizationImageArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeOrganizationImage as removeOrganizationImageResolver } from "../../../src/lib/resolvers/Mutation/removeOrganizationImage"; +import { + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + blockedUsers: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeOrganizationImage", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationRemoveOrganizationImageArgs = { + organizationId: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await removeOrganizationImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.organizationId`, async () => { + try { + const args: MutationRemoveOrganizationImageArgs = { + organizationId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await removeOrganizationImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId + is not an admin of organization with _id === args.organizationId`, async () => { + try { + const args: MutationRemoveOrganizationImageArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeOrganizationImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no organization.image exists for organization + with _id === args.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + const args: MutationRemoveOrganizationImageArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await removeOrganizationImageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual("Organization image not found"); + } + }); + + // it(`sets image field to null for organization with _id === args.organizationId + // and returns the updated organization`, async () => { + // await Organization.updateOne( + // { + // _id: testOrganization._id, + // }, + // { + // $set: { + // image: 'image', + // }, + // } + // ); + + // const args: MutationRemoveOrganizationImageArgs = { + // organizationId: testOrganization.id, + // }; + + // const context = { + // userId: testUser._id, + // }; + + // const removeOrganizationImagePayload = + // await removeOrganizationImageResolver?.({}, args, context); + + // const updatedTestOrganization = await Organization.findOne({ + // _id: testOrganization._id, + // }).lean(); + + // expect(removeOrganizationImagePayload).toEqual(updatedTestOrganization); + + // expect(removeOrganizationImagePayload?.image).toEqual(null); + // }); +}); diff --git a/__tests__/resolvers/Mutation/removePost.spec.ts b/__tests__/resolvers/Mutation/removePost.spec.ts new file mode 100644 index 0000000000..eabafe3887 --- /dev/null +++ b/__tests__/resolvers/Mutation/removePost.spec.ts @@ -0,0 +1,143 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Post, + Post, +} from "../../../src/lib/models"; +import { MutationRemovePostArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removePost as removePostResolver } from "../../../src/lib/resolvers/Mutation/removePost"; +import { + POST_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; +let testPost: Interface_Post & Document; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUsers[0]._id, + organization: testOrganization._id, + likedBy: [testUsers[0]._id], + likeCount: 1, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removePost", () => { + it(`throws NotFoundError if current user with _id === context.userId does not exist`, async () => { + try { + const args: MutationRemovePostArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await removePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no post exists with _id === args.id`, async () => { + try { + const args: MutationRemovePostArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUsers[0].id, + }; + + await removePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(POST_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if for creator of post with _id === args.id, + user._id !== context.userId`, async () => { + try { + const args: MutationRemovePostArgs = { + id: testPost.id, + }; + + const context = { + userId: testUsers[1].id, + }; + + await removePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`deletes the post with _id === args.id and returns it`, async () => { + const args: MutationRemovePostArgs = { + id: testPost.id, + }; + + const context = { + userId: testUsers[0].id, + }; + + const removePostPayload = await removePostResolver?.({}, args, context); + + expect(removePostPayload).toEqual(testPost.toObject()); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeTask.spec.ts b/__tests__/resolvers/Mutation/removeTask.spec.ts new file mode 100644 index 0000000000..2fd79fc544 --- /dev/null +++ b/__tests__/resolvers/Mutation/removeTask.spec.ts @@ -0,0 +1,194 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Event, + Task, + Interface_Task, +} from "../../../src/lib/models"; +import { MutationRemoveTaskArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeTask as removeTaskResolver } from "../../../src/lib/resolvers/Mutation/removeTask"; +import { USER_NOT_AUTHORIZED, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; +let testTask: Interface_Task & Document; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id], + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testEvent = await Event.create({ + creator: testUsers[0]._id, + registrants: [ + { + userId: testUsers[0]._id, + user: testUsers[0]._id, + }, + ], + admins: [testUsers[0]._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + eventAdmin: [testEvent._id], + }, + } + ); + + testTask = await Task.create({ + title: "title", + event: testEvent._id, + creator: testUsers[0]._id, + }); + + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $push: { + tasks: testTask._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeTask", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationRemoveTaskArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await removeTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no task exists with _id === args.id`, async () => { + try { + const args: MutationRemoveTaskArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUsers[0]._id, + }; + + await removeTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual("Task not found"); + } + }); + + it(`throws NotAuthorizedError if for creator of task with _id === args.id, user._id !== context.userId`, async () => { + try { + const args: MutationRemoveTaskArgs = { + id: testTask._id, + }; + + const context = { + userId: testUsers[1]._id, + }; + + await removeTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`removes the task with _id === args.id and returns it`, async () => { + const args: MutationRemoveTaskArgs = { + id: testTask._id, + }; + + const context = { + userId: testUsers[0]._id, + }; + + const removeTaskPayload = await removeTaskResolver?.({}, args, context); + + expect(removeTaskPayload).toEqual(testTask.toObject()); + + const testRemovedTask = await Task.findOne({ + _id: testTask._id, + }).lean(); + + expect(testRemovedTask).toEqual(null); + + const testUpdatedEvents = await Event.find({ + _id: testTask.event, + }).lean(); + + testUpdatedEvents.forEach((testUpdatedEvent) => { + testUpdatedEvent.tasks.forEach((task) => { + expect(task.toString()).not.toEqual(testTask._id.toString()); + }); + }); + }); +}); diff --git a/__tests__/resolvers/Mutation/removeUserFromGroupChat.spec.ts b/__tests__/resolvers/Mutation/removeUserFromGroupChat.spec.ts new file mode 100644 index 0000000000..b52e22ae05 --- /dev/null +++ b/__tests__/resolvers/Mutation/removeUserFromGroupChat.spec.ts @@ -0,0 +1,212 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + GroupChat, + Interface_GroupChat, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationRemoveUserFromGroupChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { removeUserFromGroupChat as removeUserFromGroupChatResolver } from "../../../src/lib/resolvers/Mutation/removeUserFromGroupChat"; +import { + CHAT_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testGroupChat: Interface_GroupChat & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testGroupChat = await GroupChat.create({ + title: "title", + creator: testUser._id, + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeUserFromGroupChat", () => { + it(`throws NotFoundError if no groupChat exists with _id === args.chatId`, async () => { + try { + const args: MutationRemoveUserFromGroupChatArgs = { + chatId: Types.ObjectId().toString(), + userId: "", + }; + + const context = { + userId: testUser.id, + }; + + await removeUserFromGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is not + an admin of the organization of groupChat with _id === args.chatId`, async () => { + try { + await GroupChat.updateOne( + { + _id: testGroupChat._id, + }, + { + $set: { + organization: testOrganization._id, + }, + } + ); + + const args: MutationRemoveUserFromGroupChatArgs = { + chatId: testGroupChat.id, + userId: "", + }; + + const context = { + userId: testUser.id, + }; + + await removeUserFromGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws UnauthorizedError if users field of groupChat with _id === args.chatId + does not contain user with _id === args.userId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + adminFor: testOrganization._id, + }, + } + ); + + const args: MutationRemoveUserFromGroupChatArgs = { + chatId: testGroupChat.id, + userId: "", + }; + + const context = { + userId: testUser.id, + }; + + await removeUserFromGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`removes user with _id === args.userId from users list field of groupChat + with _id === args.ChatId and returns the updated groupChat`, async () => { + await GroupChat.updateOne( + { + _id: testGroupChat._id, + }, + { + $push: { + users: testUser._id, + }, + } + ); + + const args: MutationRemoveUserFromGroupChatArgs = { + chatId: testGroupChat.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const removeUserFromGroupChatPayload = + await removeUserFromGroupChatResolver?.({}, args, context); + + const testRemoveUserFromGroupChatPayload = await GroupChat.findOne({ + _id: testGroupChat._id, + }).lean(); + + expect(removeUserFromGroupChatPayload).toEqual( + testRemoveUserFromGroupChatPayload + ); + }); + + it(`throws NotFoundError if no organization exists for groupChat with _id === args.chatId`, async () => { + await Organization.findOneAndRemove({ + _id: testOrganization._id, + }); + + try { + const args: MutationRemoveUserFromGroupChatArgs = { + chatId: testGroupChat.id, + userId: "", + }; + + const context = { + userId: testUser.id, + }; + + await removeUserFromGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); +}); diff --git a/__tests__/resolvers/Mutation/removeUserImage.spec.ts b/__tests__/resolvers/Mutation/removeUserImage.spec.ts new file mode 100644 index 0000000000..1e3779327b --- /dev/null +++ b/__tests__/resolvers/Mutation/removeUserImage.spec.ts @@ -0,0 +1,85 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { removeUserImage as removeUserImageResolver } from "../../../src/lib/resolvers/Mutation/removeUserImage"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> removeUserImage", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const context = { + userId: Types.ObjectId().toString(), + }; + + await removeUserImageResolver?.({}, {}, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user.image exists for currentUser + with _id === context.userId`, async () => { + try { + const context = { + userId: testUser.id, + }; + + await removeUserImageResolver?.({}, {}, context); + } catch (error: any) { + expect(error.message).toEqual("User profile image not found"); + } + }); + + // it(`sets image field to null for organization with _id === args.organizationId + // and returns the updated organization`, async () => { + // await User.updateOne( + // { + // _id: testUser._id, + // }, + // { + // $set: { + // image: 'image', + // }, + // } + // ); + + // const context = { + // userId: testUser._id, + // }; + + // const removeUserImagePayload = await removeUserImageResolver?.( + // {}, + // {}, + // context + // ); + + // const updatedTestUser = await User.findOne({ + // _id: testUser._id, + // }).lean(); + + // expect(removeUserImagePayload).toEqual(updatedTestUser); + + // expect(removeUserImagePayload?.image).toEqual(null); + // }); +}); diff --git a/__tests__/resolvers/Mutation/revokeRefreshTokenForUser.spec.ts b/__tests__/resolvers/Mutation/revokeRefreshTokenForUser.spec.ts new file mode 100644 index 0000000000..adc61a2dd4 --- /dev/null +++ b/__tests__/resolvers/Mutation/revokeRefreshTokenForUser.spec.ts @@ -0,0 +1,53 @@ +import "dotenv/config"; +import { Document } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationRevokeRefreshTokenForUserArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { revokeRefreshTokenForUser as revokeRefreshTokenForUserResolver } from "../../../src/lib/resolvers/Mutation/revokeRefreshTokenForUser"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> revokeRefreshTokenForUser", () => { + it(`revokes refresh token for the user and returns true`, async () => { + const args: MutationRevokeRefreshTokenForUserArgs = { + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const revokeRefreshTokenForUserPayload = + await revokeRefreshTokenForUserResolver?.({}, args, context); + + expect(revokeRefreshTokenForUserPayload).toEqual(true); + + const testSaveFcmTokenPayload = await User.findOne({ + _id: testUser._id, + }) + .select("tokenVersion") + .lean(); + + expect(testSaveFcmTokenPayload?.tokenVersion).toEqual( + testUser.tokenVersion + 1 + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/saveFcmToken.spec.ts b/__tests__/resolvers/Mutation/saveFcmToken.spec.ts new file mode 100644 index 0000000000..cc3ca56b59 --- /dev/null +++ b/__tests__/resolvers/Mutation/saveFcmToken.spec.ts @@ -0,0 +1,67 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationSaveFcmTokenArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { saveFcmToken as saveFcmTokenResolver } from "../../../src/lib/resolvers/Mutation/saveFcmToken"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> saveFcmToken", () => { + it(`throws NotFoundError current user with _id === context.userId does not exist`, async () => { + try { + const args: MutationSaveFcmTokenArgs = { + token: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await saveFcmTokenResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`saves the fcm token and returns true`, async () => { + const args: MutationSaveFcmTokenArgs = { + token: "fcmToken", + }; + + const context = { + userId: testUser.id, + }; + + const saveFcmTokenPayload = await saveFcmTokenResolver?.({}, args, context); + + expect(saveFcmTokenPayload).toEqual(true); + + const testSaveFcmTokenPayload = await User.findOne({ + _id: testUser._id, + }) + .select("token") + .lean(); + + expect(testSaveFcmTokenPayload?.token).toEqual("fcmToken"); + }); +}); diff --git a/__tests__/resolvers/Mutation/sendMembershipRequest.spec.ts b/__tests__/resolvers/Mutation/sendMembershipRequest.spec.ts new file mode 100644 index 0000000000..fda0a7d0cd --- /dev/null +++ b/__tests__/resolvers/Mutation/sendMembershipRequest.spec.ts @@ -0,0 +1,186 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, + MembershipRequest, + Interface_MembershipRequest, +} from "../../../src/lib/models"; +import { MutationSendMembershipRequestArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { sendMembershipRequest as sendMembershipRequestResolver } from "../../../src/lib/resolvers/Mutation/sendMembershipRequest"; +import { ORGANIZATION_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testMembershipRequest: Interface_MembershipRequest & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + }, + } + ); + + testMembershipRequest = await MembershipRequest.create({ + user: testUser._id, + organization: testOrganization._id, + }); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + } + ); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> sendMembershipRequest", () => { + it(`throws NotFoundError if the current user with _id === context.userId does not exist`, async () => { + try { + const args: MutationSendMembershipRequestArgs = { + organizationId: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await sendMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no organization exists with _id === args.organizationId`, async () => { + try { + const args: MutationSendMembershipRequestArgs = { + organizationId: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser.id, + }; + + await sendMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws ConflictError if a membershipRequest with fields user === context.userId + and organization === args.organizationId already exists`, async () => { + try { + const args: MutationSendMembershipRequestArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + await sendMembershipRequestResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual("MembershipRequest already exists"); + } + }); + + it(`creates new membershipRequest and returns it`, async () => { + await MembershipRequest.deleteOne({ + _id: testMembershipRequest._id, + }); + + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + membershipRequests: [], + }, + } + ); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + membershipRequests: [], + }, + } + ); + + const args: MutationSendMembershipRequestArgs = { + organizationId: testOrganization.id, + }; + + const context = { + userId: testUser.id, + }; + + const sendMembershipRequestPayload = await sendMembershipRequestResolver?.( + {}, + args, + context + ); + + expect(sendMembershipRequestPayload).toEqual( + expect.objectContaining({ + user: testUser._id, + organization: testOrganization._id, + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/sendMessageToDirectChat.spec.ts b/__tests__/resolvers/Mutation/sendMessageToDirectChat.spec.ts new file mode 100644 index 0000000000..07c54c8796 --- /dev/null +++ b/__tests__/resolvers/Mutation/sendMessageToDirectChat.spec.ts @@ -0,0 +1,155 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + DirectChat, + Interface_DirectChat, + Interface_DirectChatMessage, +} from "../../../src/lib/models"; +import { MutationSendMessageToDirectChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { sendMessageToDirectChat as sendMessageToDirectChatResolver } from "../../../src/lib/resolvers/Mutation/sendMessageToDirectChat"; +import { CHAT_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; +let testDirectChat: Interface_DirectChat & + Document; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testDirectChat = await DirectChat.create({ + title: "title", + creator: testUsers[0]._id, + organization: testOrganization._id, + users: [testUsers[0]._id, testUsers[1]._id], + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> sendMessageToDirectChat", () => { + it(`throws NotFoundError if no directChat exists with _id === args.chatId`, async () => { + try { + const args: MutationSendMessageToDirectChatArgs = { + chatId: Types.ObjectId().toString(), + messageContent: "", + }; + + const context = { userId: testUsers[0].id }; + + await sendMessageToDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws NotFoundError current user with _id === context.userId does not exist`, async () => { + try { + const args: MutationSendMessageToDirectChatArgs = { + chatId: testDirectChat.id, + messageContent: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await sendMessageToDirectChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`creates the directChatMessage and returns it`, async () => { + await DirectChat.updateOne( + { + _id: testDirectChat._id, + }, + { + $push: { + users: testUsers[0]._id, + }, + } + ); + + const args: MutationSendMessageToDirectChatArgs = { + chatId: testDirectChat.id, + messageContent: "messageContent", + }; + + const pubsub = { + publish: ( + _action: "MESSAGE_SENT_TO_DIRECT_CHAT", + _payload: { + messageSentToDirectChat: Interface_DirectChatMessage; + } + ) => { + return; + }, + }; + + const context = { + userId: testUsers[0].id, + pubsub, + }; + + const sendMessageToDirectChatPayload = + await sendMessageToDirectChatResolver?.({}, args, context); + + expect(sendMessageToDirectChatPayload).toEqual( + expect.objectContaining({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUsers[0]._id, + receiver: testUsers[1]._id, + messageContent: "messageContent", + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/sendMessageToGroupChat.spec.ts b/__tests__/resolvers/Mutation/sendMessageToGroupChat.spec.ts new file mode 100644 index 0000000000..042879370b --- /dev/null +++ b/__tests__/resolvers/Mutation/sendMessageToGroupChat.spec.ts @@ -0,0 +1,165 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + GroupChat, + Interface_GroupChat, + Interface_GroupChatMessage, +} from "../../../src/lib/models"; +import { MutationSendMessageToGroupChatArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { sendMessageToGroupChat as sendMessageToGroupChatResolver } from "../../../src/lib/resolvers/Mutation/sendMessageToGroupChat"; +import { + CHAT_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +let testUser: Interface_User & Document; +let testGroupChat: Interface_GroupChat & + Document; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testGroupChat = await GroupChat.create({ + title: "title", + creator: testUser._id, + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> sendMessageToGroupChat", () => { + it(`throws NotFoundError if no groupChat exists with _id === args.chatId`, async () => { + try { + const args: MutationSendMessageToGroupChatArgs = { + chatId: Types.ObjectId().toString(), + messageContent: "", + }; + + const context = { userId: testUser.id }; + + await sendMessageToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws NotFoundError current user with _id === context.userId does not exist`, async () => { + try { + const args: MutationSendMessageToGroupChatArgs = { + chatId: testGroupChat.id, + messageContent: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await sendMessageToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if users field of groupChat with _id === args.chatId + does not contain current user with _id === context.userId`, async () => { + try { + const args: MutationSendMessageToGroupChatArgs = { + chatId: testGroupChat.id, + messageContent: "", + }; + + const context = { + userId: testUser.id, + }; + + await sendMessageToGroupChatResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`creates the groupChatMessage and returns it`, async () => { + await GroupChat.updateOne( + { + _id: testGroupChat._id, + }, + { + $push: { + users: testUser._id, + }, + } + ); + + const args: MutationSendMessageToGroupChatArgs = { + chatId: testGroupChat.id, + messageContent: "messageContent", + }; + + const pubsub = { + publish: ( + _action: "MESSAGE_SENT_TO_GROUP_CHAT", + _payload: { + messageSentToGroupChat: Interface_GroupChatMessage; + } + ) => { + return; + }, + }; + + const context = { + userId: testUser.id, + pubsub, + }; + + const sendMessageToGroupChatPayload = + await sendMessageToGroupChatResolver?.({}, args, context); + + expect(sendMessageToGroupChatPayload).toEqual( + expect.objectContaining({ + groupChatMessageBelongsTo: testGroupChat._id, + sender: testUser._id, + messageContent: "messageContent", + }) + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/signUp.spec.ts b/__tests__/resolvers/Mutation/signUp.spec.ts new file mode 100644 index 0000000000..8f1e5f9931 --- /dev/null +++ b/__tests__/resolvers/Mutation/signUp.spec.ts @@ -0,0 +1,191 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { + MutationSignUpArgs, + UserType, +} from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { signUp as signUpResolver } from "../../../src/lib/resolvers/Mutation/signUp"; +import { + androidFirebaseOptions, + iosFirebaseOptions, +} from "../../../src/lib/config"; +import { ORGANIZATION_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> signUp", () => { + it(`throws ConflictError if a user already with email === args.data.email already exists`, async () => { + try { + const args: MutationSignUpArgs = { + data: { + email: testUser.email, + firstName: "firstName", + lastName: "lastName", + password: "password", + appLanguageCode: "en", + organizationUserBelongsToId: undefined, + userType: UserType.User, + }, + }; + + await signUpResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual("Email already exists"); + } + }); + + it(`creates the user and returns the created user with accessToken, refreshToken, + androidFirebaseOptions, iosFirebaseOptions`, async () => { + const email = `email${nanoid().toLowerCase()}@gmail.com`; + + const args: MutationSignUpArgs = { + data: { + email, + firstName: "firstName", + lastName: "lastName", + password: "password", + appLanguageCode: "en", + organizationUserBelongsToId: undefined, + userType: UserType.User, + }, + }; + + const signUpPayload = await signUpResolver?.({}, args, {}); + + const createdUser = await User.findOne({ + email, + }) + .select("-password") + .lean(); + + expect({ + user: signUpPayload?.user, + androidFirebaseOptions: signUpPayload?.androidFirebaseOptions, + iosFirebaseOptions: signUpPayload?.iosFirebaseOptions, + }).toEqual({ + user: createdUser, + androidFirebaseOptions, + iosFirebaseOptions, + }); + + expect(typeof signUpPayload?.accessToken).toEqual("string"); + expect(signUpPayload?.accessToken.length).toBeGreaterThan(1); + + expect(typeof signUpPayload?.refreshToken).toEqual("string"); + expect(signUpPayload?.refreshToken.length).toBeGreaterThan(1); + }); + + it(`throws NotFoundError if no organization exists with _id === args.data.organizationUserBelongsToId`, async () => { + try { + const email = `email${nanoid().toLowerCase()}@gmail.com`; + + const args: MutationSignUpArgs = { + data: { + email, + firstName: "firstName", + lastName: "lastName", + password: "password", + appLanguageCode: "en", + organizationUserBelongsToId: Types.ObjectId().toString(), + userType: UserType.User, + }, + }; + + await signUpResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`creates the user with provided organizationUserBelongsToId and returns the + created user with accessToken, refreshToken, androidFirebaseOptions, + iosFirebaseOptions`, async () => { + const email = `email${nanoid().toLowerCase()}@gmail.com`; + + const args: MutationSignUpArgs = { + data: { + email, + firstName: "firstName", + lastName: "lastName", + password: "password", + appLanguageCode: "en", + organizationUserBelongsToId: testOrganization.id, + userType: UserType.User, + }, + }; + + const signUpPayload = await signUpResolver?.({}, args, {}); + + const createdUser = await User.findOne({ + email, + }) + .select("-password") + .lean(); + + expect({ + user: signUpPayload?.user, + androidFirebaseOptions: signUpPayload?.androidFirebaseOptions, + iosFirebaseOptions: signUpPayload?.iosFirebaseOptions, + }).toEqual({ + user: createdUser, + androidFirebaseOptions, + iosFirebaseOptions, + }); + + expect(typeof signUpPayload?.accessToken).toEqual("string"); + expect(signUpPayload?.accessToken.length).toBeGreaterThan(1); + + expect(typeof signUpPayload?.refreshToken).toEqual("string"); + expect(signUpPayload?.refreshToken.length).toBeGreaterThan(1); + }); +}); diff --git a/__tests__/resolvers/Mutation/unblockUser.spec.ts b/__tests__/resolvers/Mutation/unblockUser.spec.ts new file mode 100644 index 0000000000..cdbd974650 --- /dev/null +++ b/__tests__/resolvers/Mutation/unblockUser.spec.ts @@ -0,0 +1,197 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationUnblockUserArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { unblockUser as unblockUserResolver } from "../../../src/lib/resolvers/Mutation/unblockUser"; +import { + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> unblockUser", () => { + it(`throws NotFoundError if no organization exists with with _id === args.organizationId`, async () => { + try { + const args: MutationUnblockUserArgs = { + organizationId: Types.ObjectId().toString(), + userId: "", + }; + + const context = { + userId: "", + }; + + await unblockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.userId`, async () => { + try { + const args: MutationUnblockUserArgs = { + organizationId: testOrganization.id, + userId: Types.ObjectId().toString(), + }; + + const context = { + userId: "", + }; + + await unblockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is not + an admin of the organization with _id === args.organizationId`, async () => { + try { + const args: MutationUnblockUserArgs = { + organizationId: testOrganization.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await unblockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws UnauthorizedError if user with _id === args.userId does not exist + in blockedUsers list of organization with _id === args.organizationId`, async () => { + try { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + await User.updateOne( + { + _id: testUser.id, + }, + { + $push: { + adminFor: testOrganization._id, + }, + } + ); + + const args: MutationUnblockUserArgs = { + organizationId: testOrganization.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + await unblockUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`removes the user with _id === args.userId from blockedUsers list of the + organization with _id === args.organizationId and returns the updated user`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $push: { + blockedUsers: testUser._id, + }, + } + ); + + await User.updateOne( + { + _id: testUser.id, + }, + { + $push: { + organizationsBlockedBy: testOrganization._id, + }, + } + ); + + const args: MutationUnblockUserArgs = { + organizationId: testOrganization.id, + userId: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const unblockUserPayload = await unblockUserResolver?.({}, args, context); + + const testUnblockUserPayload = await User.findOne({ + _id: testUser.id, + }) + .select(["-password"]) + .lean(); + + expect(unblockUserPayload).toEqual(testUnblockUserPayload); + }); +}); diff --git a/__tests__/resolvers/Mutation/unlikeComment.spec.ts b/__tests__/resolvers/Mutation/unlikeComment.spec.ts new file mode 100644 index 0000000000..de66c90a22 --- /dev/null +++ b/__tests__/resolvers/Mutation/unlikeComment.spec.ts @@ -0,0 +1,166 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Post, + Comment, + Interface_Comment, +} from "../../../src/lib/models"; +import { MutationUnlikeCommentArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { unlikeComment as unlikeCommentResolver } from "../../../src/lib/resolvers/Mutation/unlikeComment"; +import { COMMENT_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testComment: Interface_Comment & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); + + testComment = await Comment.create({ + text: "text", + creator: testUser._id, + post: testPost._id, + likedBy: [testUser._id], + likeCount: 1, + }); + + await Post.updateOne( + { + _id: testPost._id, + }, + { + $push: { + comments: testComment._id, + }, + $inc: { + commentCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> unlikeComment", () => { + it(`throws NotFoundError if current user with _id === context.userId does not exist`, async () => { + try { + const args: MutationUnlikeCommentArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await unlikeCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no comment exists with _id === args.id`, async () => { + try { + const args: MutationUnlikeCommentArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser._id, + }; + + await unlikeCommentResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(COMMENT_NOT_FOUND); + } + }); + + it(`removes current user with _id === context.userId from likedBy list + on comment with _id === args.id`, async () => { + const args: MutationUnlikeCommentArgs = { + id: testComment._id, + }; + + const context = { + userId: testUser._id, + }; + + const unlikeCommentPayload = await unlikeCommentResolver?.( + {}, + args, + context + ); + + const testUnlikeCommentPayload = await Comment.findOne({ + _id: testComment._id, + }).lean(); + + expect(unlikeCommentPayload).toEqual(testUnlikeCommentPayload); + }); + + it(`returns the comment with _id === args.id without any mutation if current user + with _id === context.userId does not exist in likedBy list of the comment`, async () => { + const args: MutationUnlikeCommentArgs = { + id: testComment._id, + }; + + const context = { + userId: testUser._id, + }; + + const unlikeCommentPayload = await unlikeCommentResolver?.( + {}, + args, + context + ); + + const testUnlikeCommentPayload = await Comment.findOne({ + _id: testComment._id, + }).lean(); + + expect(unlikeCommentPayload).toEqual(testUnlikeCommentPayload); + }); +}); diff --git a/__tests__/resolvers/Mutation/unlikePost.spec.ts b/__tests__/resolvers/Mutation/unlikePost.spec.ts new file mode 100644 index 0000000000..409f979c7b --- /dev/null +++ b/__tests__/resolvers/Mutation/unlikePost.spec.ts @@ -0,0 +1,137 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Post, + Post, +} from "../../../src/lib/models"; +import { MutationUnlikePostArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { unlikePost as unlikePostResolver } from "../../../src/lib/resolvers/Mutation/unlikePost"; +import { POST_NOT_FOUND, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testPost: Interface_Post & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + likedBy: [testUser._id], + likeCount: 1, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> unlikePost", () => { + it(`throws NotFoundError if current user with _id === context.userId does not exist`, async () => { + try { + const args: MutationUnlikePostArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await unlikePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no post exists with _id === args.id`, async () => { + try { + const args: MutationUnlikePostArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser._id, + }; + + await unlikePostResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(POST_NOT_FOUND); + } + }); + + it(`removes current user with _id === context.userId from likedBy list + on post with _id === args.id`, async () => { + const args: MutationUnlikePostArgs = { + id: testPost._id, + }; + + const context = { + userId: testUser._id, + }; + + const unlikePostPayload = await unlikePostResolver?.({}, args, context); + + const testUnlikePostPayload = await Post.findOne({ + _id: testPost._id, + }).lean(); + + expect(unlikePostPayload).toEqual(testUnlikePostPayload); + }); + + it(`returns the post with _id === args.id without any mutation if current user + with _id === context.userId does not exist in likedBy list of the post`, async () => { + const args: MutationUnlikePostArgs = { + id: testPost._id, + }; + + const context = { + userId: testUser._id, + }; + + const unlikePostPayload = await unlikePostResolver?.({}, args, context); + + const testUnlikePostPayload = await Post.findOne({ + _id: testPost._id, + }).lean(); + + expect(unlikePostPayload).toEqual(testUnlikePostPayload); + }); +}); diff --git a/__tests__/resolvers/Mutation/unregisterForEventByUser.spec.ts b/__tests__/resolvers/Mutation/unregisterForEventByUser.spec.ts new file mode 100644 index 0000000000..a6b27abc90 --- /dev/null +++ b/__tests__/resolvers/Mutation/unregisterForEventByUser.spec.ts @@ -0,0 +1,197 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Event, + Interface_Event, +} from "../../../src/lib/models"; +import { MutationUnregisterForEventByUserArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { unregisterForEventByUser as unregisterForEventByUserResolver } from "../../../src/lib/resolvers/Mutation/unregisterForEventByUser"; +import { + EVENT_NOT_FOUND, + USER_ALREADY_UNREGISTERED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testEvent = await Event.create({ + creator: testUser._id, + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdEvents: [testEvent._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> unregisterForEventByUser", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationUnregisterForEventByUserArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await unregisterForEventByUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no event exists with _id === args.id`, async () => { + try { + const args: MutationUnregisterForEventByUserArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser._id, + }; + + await unregisterForEventByUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`throws NotFoundError if current user with _id === context.userId is + not a registrant of event with _id === args.id`, async () => { + try { + const args: MutationUnregisterForEventByUserArgs = { + id: testEvent._id, + }; + + const context = { + userId: testUser._id, + }; + + await unregisterForEventByUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`unregisters current user with _id === context.userId from event with + _id === args.id`, async () => { + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $push: { + registrants: { + userId: testUser._id, + user: testUser._id, + status: "ACTIVE", + }, + }, + } + ); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + registeredEvents: testEvent._id, + }, + } + ); + + const args: MutationUnregisterForEventByUserArgs = { + id: testEvent._id, + }; + + const context = { + userId: testUser._id, + }; + + const unregisterForEventByUserPayload = + await unregisterForEventByUserResolver?.({}, args, context); + + const testUnregisterForEventByUserPayload = await Event.findOne({ + _id: testEvent._id, + }).lean(); + + expect(unregisterForEventByUserPayload).toEqual( + testUnregisterForEventByUserPayload + ); + }); + + it(`throws NotFoundError if current user with _id === context.userId has + already unregistered from the event with _id === args.id`, async () => { + try { + const args: MutationUnregisterForEventByUserArgs = { + id: testEvent._id, + }; + + const context = { + userId: testUser._id, + }; + + await unregisterForEventByUserResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_ALREADY_UNREGISTERED); + } + }); +}); diff --git a/__tests__/resolvers/Mutation/updateEvent.spec.ts b/__tests__/resolvers/Mutation/updateEvent.spec.ts new file mode 100644 index 0000000000..82346f417e --- /dev/null +++ b/__tests__/resolvers/Mutation/updateEvent.spec.ts @@ -0,0 +1,193 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Event, + Interface_Event, +} from "../../../src/lib/models"; +import { + MutationUpdateEventArgs, + Recurrance, +} from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updateEvent as updateEventResolver } from "../../../src/lib/resolvers/Mutation/updateEvent"; +import { + EVENT_NOT_FOUND, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testEvent = await Event.create({ + creator: testUser._id, + registrants: [{ userId: testUser._id, user: testUser._id }], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updateEvent", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationUpdateEventArgs = { + id: "", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await updateEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no event exists with _id === args.id`, async () => { + try { + const args: MutationUpdateEventArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser._id, + }; + + await updateEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if current user with _id === context.userId is + not an admin of event with _id === args.id`, async () => { + try { + const args: MutationUpdateEventArgs = { + id: testEvent._id, + }; + + const context = { + userId: testUser._id, + }; + + await updateEventResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`updates the event with _id === args.id and returns the updated event`, async () => { + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $push: { + admins: testUser._id, + }, + } + ); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + eventAdmin: testEvent._id, + }, + } + ); + + const args: MutationUpdateEventArgs = { + id: testEvent._id, + data: { + allDay: false, + description: "newDescription", + endDate: new Date().toUTCString(), + endTime: new Date().toUTCString(), + isPublic: false, + isRegisterable: false, + latitude: 1, + longitude: 1, + location: "newLocation", + recurring: false, + startDate: new Date().toUTCString(), + startTime: new Date().toUTCString(), + title: "newTitle", + recurrance: Recurrance.Daily, + }, + }; + + const context = { + userId: testUser._id, + }; + + const updateEventPayload = await updateEventResolver?.({}, args, context); + + const testUpdateEventPayload = await Event.findOne({ + _id: testEvent._id, + }).lean(); + + expect(updateEventPayload).toEqual(testUpdateEventPayload); + }); +}); diff --git a/__tests__/resolvers/Mutation/updateLanguage.spec.ts b/__tests__/resolvers/Mutation/updateLanguage.spec.ts new file mode 100644 index 0000000000..83f1f4c4b8 --- /dev/null +++ b/__tests__/resolvers/Mutation/updateLanguage.spec.ts @@ -0,0 +1,88 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User, Organization } from "../../../src/lib/models"; +import { MutationUpdateLanguageArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updateLanguage as updateLanguageResolver } from "../../../src/lib/resolvers/Mutation/updateLanguage"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updateLanguage", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationUpdateLanguageArgs = { + languageCode: "newLanguageCode", + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await updateLanguageResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`updates the organization with _id === args.id and returns the updated organization`, async () => { + const args: MutationUpdateLanguageArgs = { + languageCode: "newLanguageCode", + }; + + const context = { + userId: testUser._id, + }; + + const updateLanguagePayload = await updateLanguageResolver?.( + {}, + args, + context + ); + + const testUpdateLanguagePayload = await User.findOne({ + _id: testUser._id, + }).lean(); + + expect(updateLanguagePayload).toEqual(testUpdateLanguagePayload); + }); +}); diff --git a/__tests__/resolvers/Mutation/updateOrganization.spec.ts b/__tests__/resolvers/Mutation/updateOrganization.spec.ts new file mode 100644 index 0000000000..9780eedab8 --- /dev/null +++ b/__tests__/resolvers/Mutation/updateOrganization.spec.ts @@ -0,0 +1,143 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationUpdateOrganizationArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updateOrganization as updateOrganizationResolver } from "../../../src/lib/resolvers/Mutation/updateOrganization"; +import { + ORGANIZATION_NOT_FOUND, + USER_NOT_AUTHORIZED, +} from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + members: [testUser._id], + visibleInSearch: true, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updateOrganization", () => { + it(`throws NotFoundError if no organization exists with _id === args.id`, async () => { + try { + const args: MutationUpdateOrganizationArgs = { + id: Types.ObjectId().toString(), + }; + + const context = { + userId: testUser._id, + }; + + await updateOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws UnauthorizedError if user with _id === context.userId is not an admin + of organization with _id === args.id`, async () => { + try { + const args: MutationUpdateOrganizationArgs = { + id: testOrganization._id, + }; + + const context = { + userId: testUser._id, + }; + + await updateOrganizationResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`updates the organization with _id === args.id and returns the updated organization`, async () => { + await Organization.updateOne( + { + _id: testOrganization._id, + }, + { + $set: { + admins: [testUser._id], + }, + } + ); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + adminFor: [testOrganization._id], + }, + } + ); + + const args: MutationUpdateOrganizationArgs = { + id: testOrganization._id, + data: { + description: "newDescription", + isPublic: false, + name: "newName", + visibleInSearch: false, + }, + }; + + const context = { + userId: testUser._id, + }; + + const updateOrganizationPayload = await updateOrganizationResolver?.( + {}, + args, + context + ); + + const testUpdateOrganizationPayload = await Organization.findOne({ + _id: testOrganization._id, + }).lean(); + + expect(updateOrganizationPayload).toEqual(testUpdateOrganizationPayload); + }); +}); diff --git a/__tests__/resolvers/Mutation/updatePluginInstalledOrgs.spec.ts b/__tests__/resolvers/Mutation/updatePluginInstalledOrgs.spec.ts new file mode 100644 index 0000000000..fcda372801 --- /dev/null +++ b/__tests__/resolvers/Mutation/updatePluginInstalledOrgs.spec.ts @@ -0,0 +1,114 @@ +import "dotenv/config"; +import { Document } from "mongoose"; +import { + Interface_User, + User, + Organization, + Plugin, + Interface_Plugin, + Interface_Organization, +} from "../../../src/lib/models"; +import { MutationUpdatePluginInstalledOrgsArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updatePluginInstalledOrgs as updatePluginInstalledOrgsResolver } from "../../../src/lib/resolvers/Mutation/updatePluginInstalledOrgs"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testPlugin: Interface_Plugin & Document; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPlugin = await Plugin.create({ + pluginName: "pluginName", + pluginCreatedBy: `${testUser.firstName} ${testUser.lastName}`, + pluginDesc: "pluginDesc", + pluginInstallStatus: false, + installedOrgs: [testOrganization._id], + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updatePluginInstalledOrgs", () => { + it(`if organization with _id === args.orgId already exists in plugin.installedOrgs + for plugin with _id === args.id, removes it from plugin.installedOrgs`, async () => { + const args: MutationUpdatePluginInstalledOrgsArgs = { + id: testPlugin._id, + orgId: testOrganization._id, + }; + + const context = { + userId: testUser._id, + }; + + const updatePluginInstalledOrgsPayload = + await updatePluginInstalledOrgsResolver?.({}, args, context); + + const testUpdatePluginStatusPayload = await Plugin.findOne({ + _id: testPlugin._id, + }).lean(); + + expect(updatePluginInstalledOrgsPayload).toEqual( + testUpdatePluginStatusPayload + ); + }); + + it(`if organization with _id === args.orgId doesn't exist in plugin.installedOrgs + for plugin with _id === args.id, adds it to plugin.installedOrgs`, async () => { + const args: MutationUpdatePluginInstalledOrgsArgs = { + id: testPlugin._id, + orgId: testOrganization._id, + }; + + const context = { + userId: testUser._id, + }; + + const updatePluginInstalledOrgsPayload = + await updatePluginInstalledOrgsResolver?.({}, args, context); + + const testUpdatePluginStatusPayload = await Plugin.findOne({ + _id: testPlugin._id, + }).lean(); + + expect(updatePluginInstalledOrgsPayload).toEqual( + testUpdatePluginStatusPayload + ); + }); +}); diff --git a/__tests__/resolvers/Mutation/updatePluginStatus.spec.ts b/__tests__/resolvers/Mutation/updatePluginStatus.spec.ts new file mode 100644 index 0000000000..ba40808c8d --- /dev/null +++ b/__tests__/resolvers/Mutation/updatePluginStatus.spec.ts @@ -0,0 +1,89 @@ +import "dotenv/config"; +import { Document } from "mongoose"; +import { + Interface_User, + User, + Organization, + Plugin, + Interface_Plugin, +} from "../../../src/lib/models"; +import { MutationUpdatePluginStatusArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updatePluginStatus as updatePluginStatusResolver } from "../../../src/lib/resolvers/Mutation/updatePluginStatus"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testPlugin: Interface_Plugin & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPlugin = await Plugin.create({ + pluginName: "pluginName", + pluginCreatedBy: `${testUser.firstName} ${testUser.lastName}`, + pluginDesc: "pluginDesc", + pluginInstallStatus: false, + installedOrgs: [testOrganization._id], + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updatePluginStatus", () => { + it(`updates the pluginInstallStatus field of plugin with + _id === args.id and returns it`, async () => { + const args: MutationUpdatePluginStatusArgs = { + id: testPlugin._id, + status: true, + }; + + const context = { + userId: testUser._id, + }; + + const updatePluginStatusPayload = await updatePluginStatusResolver?.( + {}, + args, + context + ); + + const updatedTestPlugin = await Plugin.findOne({ + _id: testPlugin._id, + }).lean(); + + expect(updatePluginStatusPayload).toEqual(updatedTestPlugin); + }); +}); diff --git a/__tests__/resolvers/Mutation/updateTask.spec.ts b/__tests__/resolvers/Mutation/updateTask.spec.ts new file mode 100644 index 0000000000..7eb41eb21b --- /dev/null +++ b/__tests__/resolvers/Mutation/updateTask.spec.ts @@ -0,0 +1,177 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { + Interface_User, + User, + Organization, + Event, + Task, + Interface_Task, +} from "../../../src/lib/models"; +import { MutationUpdateTaskArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updateTask as updateTaskResolver } from "../../../src/lib/resolvers/Mutation/updateTask"; +import { USER_NOT_AUTHORIZED, USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testTasks: (Interface_Task & Document)[]; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testEvent = await Event.create({ + creator: testUser._id, + registrants: [{ userId: testUser._id, user: testUser._id }], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + eventAdmin: [testEvent._id], + }, + } + ); + + testTasks = await Task.insertMany([ + { + title: "title", + event: testEvent._id, + creator: testUser._id, + }, + { + title: "title", + event: testEvent._id, + creator: Types.ObjectId().toString(), + }, + ]); + + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $push: { + tasks: [testTasks[0]._id, testTasks[1]._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updateTask", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationUpdateTaskArgs = { + id: "", + data: {}, + }; + + const context = { userId: Types.ObjectId().toString() }; + + await updateTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no task exists with _id === args.id`, async () => { + try { + const args: MutationUpdateTaskArgs = { + id: Types.ObjectId().toString(), + data: {}, + }; + + const context = { userId: testUser._id }; + + await updateTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual("Task not found"); + } + }); + + it(`throws NotAuthorizedError if post.creator !== context.userId post with _id === args.id, `, async () => { + try { + const args: MutationUpdateTaskArgs = { + id: testTasks[1]._id, + data: {}, + }; + + const context = { + userId: testUser._id, + }; + + await updateTaskResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`updates the task with _id === args.id and returns it`, async () => { + const args: MutationUpdateTaskArgs = { + id: testTasks[0]._id, + data: { + title: "newTitle", + deadline: Date.now().toString(), + description: "newDescription", + }, + }; + + const context = { userId: testUser._id }; + + const updateTaskPayload = await updateTaskResolver?.({}, args, context); + + const updatedTestTask = await Task.findOne({ + _id: testTasks[0]._id, + }).lean(); + + expect(updateTaskPayload).toEqual(updatedTestTask); + }); +}); diff --git a/__tests__/resolvers/Mutation/updateUserProfile.spec.ts b/__tests__/resolvers/Mutation/updateUserProfile.spec.ts new file mode 100644 index 0000000000..5f88f9d4c0 --- /dev/null +++ b/__tests__/resolvers/Mutation/updateUserProfile.spec.ts @@ -0,0 +1,90 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationUpdateUserProfileArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updateUserProfile as updateUserProfileResolver } from "../../../src/lib/resolvers/Mutation/updateUserProfile"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updateUserProfile", () => { + it(`throws NotFoundError if no user exists with _id === context.userId`, async () => { + try { + const args: MutationUpdateUserProfileArgs = { + data: {}, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + await updateUserProfileResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws ConflictError if args.data.email is already registered for another user'`, async () => { + try { + const args: MutationUpdateUserProfileArgs = { + data: { + email: testUser.email, + }, + }; + + const context = { + userId: testUser._id, + }; + + await updateUserProfileResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual("Email already exists"); + } + }); + + it(`updates current user's user object and returns the object`, async () => { + const args: MutationUpdateUserProfileArgs = { + data: { + email: `email${nanoid().toLowerCase()}@gmail.com`, + firstName: "newFirstName", + lastName: "newLastName", + }, + }; + + const context = { + userId: testUser._id, + }; + + const updateUserProfilePayload = await updateUserProfileResolver?.( + {}, + args, + context + ); + + expect(updateUserProfilePayload).toEqual({ + ...testUser.toObject(), + email: args.data?.email, + firstName: "newFirstName", + lastName: "newLastName", + }); + }); +}); diff --git a/__tests__/resolvers/Mutation/updateUserType.spec.ts b/__tests__/resolvers/Mutation/updateUserType.spec.ts new file mode 100644 index 0000000000..0d4cf41cbf --- /dev/null +++ b/__tests__/resolvers/Mutation/updateUserType.spec.ts @@ -0,0 +1,102 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { nanoid } from "nanoid"; +import { Interface_User, User } from "../../../src/lib/models"; +import { MutationUpdateUserTypeArgs } from "../../../src/generated/graphqlCodegen"; +import { connect, disconnect } from "../../../src/db"; +import { updateUserType as updateUserTypeResolver } from "../../../src/lib/resolvers/Mutation/updateUserType"; +import { USER_NOT_AUTHORIZED, USER_NOT_FOUND } from "../../../src/constants"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> updateUserType", () => { + it(`throws UnauthorizedError if user with _id === context.userId is not a SUPERADMIN`, async () => { + try { + const args: MutationUpdateUserTypeArgs = { + data: {}, + }; + + const context = { + userId: testUsers[0]._id, + }; + + await updateUserTypeResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_AUTHORIZED); + } + }); + + it(`throws NotFoundError if no user exists with _id === args.data.id`, async () => { + try { + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + userType: "SUPERADMIN", + }, + { + new: true, + } + ); + + const args: MutationUpdateUserTypeArgs = { + data: { id: Types.ObjectId().toString() }, + }; + const context = { userId: testUsers[0]._id }; + + await updateUserTypeResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`updates user.userType of user with _id === args.data.id to args.data.userType`, async () => { + const args: MutationUpdateUserTypeArgs = { + data: { id: testUsers[1]._id, userType: "BLOCKED" }, + }; + const context = { userId: testUsers[0]._id }; + + const updateUserTypePayload = await updateUserTypeResolver?.( + {}, + args, + context + ); + + expect(updateUserTypePayload).toEqual(true); + + const updatedTestUser = await User.findOne({ + _id: testUsers[1]._id, + }) + .select("userType") + .lean(); + + expect(updatedTestUser!.userType).toEqual("BLOCKED"); + }); +}); diff --git a/__tests__/resolvers/Organization/admins.spec.ts b/__tests__/resolvers/Organization/admins.spec.ts new file mode 100644 index 0000000000..3dc9961160 --- /dev/null +++ b/__tests__/resolvers/Organization/admins.spec.ts @@ -0,0 +1,69 @@ +import "dotenv/config"; +import { admins as adminsResolver } from "../../../src/lib/resolvers/Organization/admins"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization: + | (Interface_Organization & Document) + | null; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Organization -> admins", () => { + it(`returns all user objects for parent.admins`, async () => { + const parent = testOrganization!.toObject(); + + const adminsPayload = await adminsResolver?.(parent, {}, {}); + + const admins = await User.find({ + _id: { + $in: testOrganization!.admins, + }, + }).lean(); + + expect(adminsPayload).toEqual(admins); + }); +}); diff --git a/__tests__/resolvers/Organization/blockedUsers.spec.ts b/__tests__/resolvers/Organization/blockedUsers.spec.ts new file mode 100644 index 0000000000..739792e1ef --- /dev/null +++ b/__tests__/resolvers/Organization/blockedUsers.spec.ts @@ -0,0 +1,70 @@ +import "dotenv/config"; +import { blockedUsers as blockedUsersResolver } from "../../../src/lib/resolvers/Organization/blockedUsers"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization: + | (Interface_Organization & Document) + | null; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + blockedUsers: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Organization -> blockedUsers", () => { + it(`returns all user objects for parent.blockedUsers`, async () => { + const parent = testOrganization!.toObject(); + + const blockedUsersPayload = await blockedUsersResolver?.(parent, {}, {}); + + const blockedUsers = await User.find({ + _id: { + $in: testOrganization!.blockedUsers, + }, + }).lean(); + + expect(blockedUsersPayload).toEqual(blockedUsers); + }); +}); diff --git a/__tests__/resolvers/Organization/creator.spec.ts b/__tests__/resolvers/Organization/creator.spec.ts new file mode 100644 index 0000000000..4a497066be --- /dev/null +++ b/__tests__/resolvers/Organization/creator.spec.ts @@ -0,0 +1,109 @@ +import "dotenv/config"; +import { creator as creatorResolver } from "../../../src/lib/resolvers/Organization/creator"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_Organization, + Interface_User, +} from "../../../src/lib/models"; +import { Document, Types } from "mongoose"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +let testOrganization: + | (Interface_Organization & Document) + | null; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Organization -> creator", () => { + it(`throws NotFoundError if no user exists with _id === parent.creator`, async () => { + try { + testOrganization = await Organization.findOneAndUpdate( + { + _id: testOrganization!._id, + }, + { + $set: { + creator: Types.ObjectId().toString(), + }, + }, + { + new: true, + } + ); + + const parent = testOrganization!.toObject(); + + await creatorResolver?.(parent, {}, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`returns user object for parent.creator`, async () => { + testOrganization = await Organization.findOneAndUpdate( + { + _id: testOrganization!._id, + }, + { + $set: { + creator: testUser._id, + }, + }, + { + new: true, + } + ); + + const parent = testOrganization!.toObject(); + + const creatorPayload = await creatorResolver?.(parent, {}, {}); + + const creator = await User.findOne({ + _id: testOrganization!.creator, + }).lean(); + + expect(creatorPayload).toEqual(creator); + }); +}); diff --git a/__tests__/resolvers/Organization/members.spec.ts b/__tests__/resolvers/Organization/members.spec.ts new file mode 100644 index 0000000000..c3aa927e27 --- /dev/null +++ b/__tests__/resolvers/Organization/members.spec.ts @@ -0,0 +1,69 @@ +import "dotenv/config"; +import { members as membersResolver } from "../../../src/lib/resolvers/Organization/members"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Interface_Organization, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization: + | (Interface_Organization & Document) + | null; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Organization -> members", () => { + it(`returns all user objects for parent.members`, async () => { + const parent = testOrganization!.toObject(); + + const membersPayload = await membersResolver?.(parent, {}, {}); + + const members = await User.find({ + _id: { + $in: testOrganization!.members, + }, + }).lean(); + + expect(membersPayload).toEqual(members); + }); +}); diff --git a/__tests__/resolvers/Organization/membershipRequests.spec.ts b/__tests__/resolvers/Organization/membershipRequests.spec.ts new file mode 100644 index 0000000000..e594cf5b0a --- /dev/null +++ b/__tests__/resolvers/Organization/membershipRequests.spec.ts @@ -0,0 +1,107 @@ +import "dotenv/config"; +import { membershipRequests as membershipRequestsResolver } from "../../../src/lib/resolvers/Organization/membershipRequests"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + MembershipRequest, + Interface_Organization, +} from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization: + | (Interface_Organization & Document) + | null; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + const testMembershipRequest = await MembershipRequest.create({ + user: testUser._id, + organization: testOrganization._id, + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + }, + { + new: true, + } + ); + + testOrganization = await Organization.findOneAndUpdate( + { + _id: testOrganization._id, + }, + { + $push: { + membershipRequests: testMembershipRequest._id, + }, + }, + { + new: true, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Organization -> membershipRequests", () => { + it(`returns all membershipRequest objects for parent.membershipRequests`, async () => { + const parent = testOrganization!.toObject(); + + const membershipRequestsPayload = await membershipRequestsResolver?.( + parent, + {}, + {} + ); + + const membershipRequests = await MembershipRequest.find({ + _id: { + $in: testOrganization!.membershipRequests, + }, + }).lean(); + + expect(membershipRequestsPayload).toEqual(membershipRequests); + }); +}); diff --git a/__tests__/resolvers/Query/checkAuth.spec.ts b/__tests__/resolvers/Query/checkAuth.spec.ts new file mode 100644 index 0000000000..1fb3e21da6 --- /dev/null +++ b/__tests__/resolvers/Query/checkAuth.spec.ts @@ -0,0 +1,48 @@ +import "dotenv/config"; +import { connect, disconnect } from "../../../src/db"; +import { checkAuth as checkAuthResolver } from "../../../src/lib/resolvers/Query/checkAuth"; +import { Types } from "mongoose"; +import { User } from "../../../src/lib/models"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> checkAuth", () => { + it("throws NotFoundError if no user exists with _id === context.userId", async () => { + try { + const context = { + userId: Types.ObjectId().toString(), + }; + + await checkAuthResolver?.({}, {}, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it("returns user object", async () => { + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const context = { + userId: testUser._id, + }; + + const user = await checkAuthResolver?.({}, {}, context); + + expect(user).toEqual(testUser.toObject()); + }); +}); diff --git a/__tests__/resolvers/Query/comments.spec.ts b/__tests__/resolvers/Query/comments.spec.ts new file mode 100644 index 0000000000..32e70f0bd3 --- /dev/null +++ b/__tests__/resolvers/Query/comments.spec.ts @@ -0,0 +1,99 @@ +import "dotenv/config"; +import { comments as commentsResolver } from "../../../src/lib/resolvers/Query/comments"; +import { connect, disconnect } from "../../../src/db"; +import { Comment, Post, User, Organization } from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); + + const testComment = await Comment.create({ + text: "text", + creator: testUser._id, + post: testPost._id, + }); + + await Post.updateOne( + { + _id: testPost._id, + }, + { + $push: { + comments: [testComment._id], + }, + $inc: { + commentCount: 1, + }, + } + ); + + await Comment.updateOne( + { + _id: testComment._id, + }, + { + $push: { + likedBy: testUser._id, + }, + $inc: { + likeCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> comments", () => { + it(`returns list of all existing comments with populated fields:- creator + , post, likedBy`, async () => { + const comments = await Comment.find() + .populate("creator", "-password") + .populate("post") + .populate("likedBy") + .lean(); + + const commentsPayload = await commentsResolver?.({}, {}, {}); + + expect(commentsPayload).toEqual(comments); + }); +}); diff --git a/__tests__/resolvers/Query/commentsByPost.spec.ts b/__tests__/resolvers/Query/commentsByPost.spec.ts new file mode 100644 index 0000000000..d82d86fbc6 --- /dev/null +++ b/__tests__/resolvers/Query/commentsByPost.spec.ts @@ -0,0 +1,175 @@ +import "dotenv/config"; +import { connect, disconnect } from "../../../src/db"; +import { commentsByPost as commentsByPostResolver } from "../../../src/lib/resolvers/Query/commentsByPost"; +import { + Comment, + User, + Post, + Organization, + Interface_Post, + Interface_Organization, + Interface_User, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Document, Types } from "mongoose"; +import { + COMMENT_NOT_FOUND, + ORGANIZATION_NOT_FOUND, + POST_NOT_FOUND, + USER_NOT_FOUND, +} from "../../../src/constants"; +import { QueryCommentsByPostArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testOrganization: Interface_Organization & + Document; +let testPost: Interface_Post & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); + + const testComment = await Comment.create({ + text: "text", + creator: testUser._id, + post: testPost._id, + }); + + await Post.updateOne( + { + _id: testPost._id, + }, + { + $push: { + comments: [testComment._id], + }, + $inc: { + commentCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> commentsByPost", () => { + it(`returns list of all comments for post with _id === args.id + populated with creator, post and likedBy`, async () => { + const args: QueryCommentsByPostArgs = { + id: testPost._id, + }; + + const commentsByPostPayload = await commentsByPostResolver?.({}, args, {}); + + const commentsByPost = await Comment.find({ + post: testPost._id, + }) + .populate("creator", "-password") + .populate("post") + .populate("likedBy") + .lean(); + + expect(commentsByPostPayload).toEqual(commentsByPost); + }); + + it(`throws NotFoundError if no organization exists with _id === post.organization + for post with _id === args.id`, async () => { + try { + await Organization.deleteOne({ + _id: testOrganization._id, + }); + + const args: QueryCommentsByPostArgs = { + id: testPost._id, + }; + + await commentsByPostResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no post exists with _id === args.id`, async () => { + try { + await Post.deleteOne({ + _id: testPost._id, + }); + + const args: QueryCommentsByPostArgs = { + id: testPost._id, + }; + + await commentsByPostResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(POST_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no creator exists for first comment for + post with id === args.id`, async () => { + try { + await User.deleteOne({ + _id: testUser._id, + }); + + const args: QueryCommentsByPostArgs = { + id: testPost._id, + }; + + await commentsByPostResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no comment exists for post with + _id === args.id`, async () => { + try { + const args: QueryCommentsByPostArgs = { + id: Types.ObjectId().toString(), + }; + + await commentsByPostResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(COMMENT_NOT_FOUND); + } + }); +}); diff --git a/__tests__/resolvers/Query/directChatMessages.spec.ts b/__tests__/resolvers/Query/directChatMessages.spec.ts new file mode 100644 index 0000000000..319f4a84f8 --- /dev/null +++ b/__tests__/resolvers/Query/directChatMessages.spec.ts @@ -0,0 +1,77 @@ +import "dotenv/config"; +import { directChatMessages as directChatMessagesResolver } from "../../../src/lib/resolvers/Query/directChatMessages"; +import { connect, disconnect } from "../../../src/db"; +import { + DirectChat, + DirectChatMessage, + Organization, + User, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testDirectChat = await DirectChat.create({ + creator: testUser._id, + organization: testOrganization._id, + users: [testUser._id], + }); + + await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUser._id, + receiver: testUser._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> directChatMessages", () => { + it("returns list of all existing directChatMessages", async () => { + const directChatMessagesPayload = await directChatMessagesResolver?.( + {}, + {}, + {} + ); + + const directChatMessages = await DirectChatMessage.find().lean(); + + expect(directChatMessagesPayload).toEqual(directChatMessages); + }); +}); diff --git a/__tests__/resolvers/Query/directChats.spec.ts b/__tests__/resolvers/Query/directChats.spec.ts new file mode 100644 index 0000000000..19e44b96b2 --- /dev/null +++ b/__tests__/resolvers/Query/directChats.spec.ts @@ -0,0 +1,82 @@ +import "dotenv/config"; +import { directChats as directChatsResolver } from "../../../src/lib/resolvers/Query/directChats"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id], + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testDirectChat = await DirectChat.create({ + creator: testUsers[0]._id, + organization: testOrganization._id, + users: [testUsers[0]._id], + }); + + await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChat._id, + sender: testUsers[0]._id, + receiver: testUsers[1]._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> directChats", () => { + it(`returns list of all existing directChats`, async () => { + const directChatsPayload = await directChatsResolver?.({}, {}, {}); + + const directChats = await DirectChat.find().lean(); + + expect(directChatsPayload).toEqual(directChats); + }); +}); diff --git a/__tests__/resolvers/Query/directChatsByUserID.spec.ts b/__tests__/resolvers/Query/directChatsByUserID.spec.ts new file mode 100644 index 0000000000..d9403813d1 --- /dev/null +++ b/__tests__/resolvers/Query/directChatsByUserID.spec.ts @@ -0,0 +1,93 @@ +import "dotenv/config"; +import { Document, Types } from "mongoose"; +import { connect, disconnect } from "../../../src/db"; +import { directChatsByUserID as directChatsByUserIDResolver } from "../../../src/lib/resolvers/Query/directChatsByUserID"; +import { + User, + Organization, + DirectChat, + Interface_User, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { QueryDirectChatsByUserIdArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + await DirectChat.create({ + creator: testUser._id, + organization: testOrganization._id, + users: [testUser._id], + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> directChatsByUserID", () => { + it(`throws NotFoundError if no directChats exists with directChats.users + containing user with _id === args.id`, async () => { + try { + const args: QueryDirectChatsByUserIdArgs = { + id: Types.ObjectId().toString(), + }; + + await directChatsByUserIDResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual("DirectChats not found"); + } + }); + + it(`returns list of all directChats with directChat.users containing the user + with _id === args.id`, async () => { + const args: QueryDirectChatsByUserIdArgs = { + id: testUser._id, + }; + + const directChatsByUserIdPayload = await directChatsByUserIDResolver?.( + {}, + args, + {} + ); + + const directChatsByUserId = await DirectChat.find({ + users: testUser._id, + }).lean(); + + expect(directChatsByUserIdPayload).toEqual(directChatsByUserId); + }); +}); diff --git a/__tests__/resolvers/Query/directChatsMessagesByChatID.spec.ts b/__tests__/resolvers/Query/directChatsMessagesByChatID.spec.ts new file mode 100644 index 0000000000..e8d6827446 --- /dev/null +++ b/__tests__/resolvers/Query/directChatsMessagesByChatID.spec.ts @@ -0,0 +1,131 @@ +import "dotenv/config"; +import { CHAT_NOT_FOUND } from "../../../src/constants"; +import { directChatsMessagesByChatID as directChatsMessagesByChatIDResolver } from "../../../src/lib/resolvers/Query/directChatsMessagesByChatID"; +import { connect, disconnect } from "../../../src/db"; +import { Document, Types } from "mongoose"; +import { + User, + Organization, + DirectChat, + Interface_DirectChat, + DirectChatMessage, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { QueryDirectChatsMessagesByChatIdArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testDirectChats: (Interface_DirectChat & + Document)[]; + +beforeAll(async () => { + await connect(); + + const testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }, + ]); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id], + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testDirectChats = await DirectChat.insertMany([ + { + creator: testUsers[0]._id, + organization: testOrganization._id, + users: [testUsers[0]._id, testUsers[1]._id], + }, + { + creator: testUsers[1]._id, + organization: testOrganization._id, + users: [testUsers[1]._id], + }, + ]); + + await DirectChatMessage.create({ + directChatMessageBelongsTo: testDirectChats[0]._id, + sender: testUsers[0]._id, + receiver: testUsers[1]._id, + createdAt: new Date(), + messageContent: "messageContent", + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> directChatsMessagesByChatID", () => { + it(`throws NotFoundError if no directChat exists with _id === args.id`, async () => { + try { + const args: QueryDirectChatsMessagesByChatIdArgs = { + id: Types.ObjectId().toString(), + }; + + await directChatsMessagesByChatIDResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`throws NotFoundError if no directChatMessages exist + for directChat with _id === args.id`, async () => { + try { + const args: QueryDirectChatsMessagesByChatIdArgs = { + id: testDirectChats[1]._id, + }; + + await directChatsMessagesByChatIDResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(CHAT_NOT_FOUND); + } + }); + + it(`returns list of all directChatMessages found + for directChat with _id === args.id`, async () => { + const args: QueryDirectChatsMessagesByChatIdArgs = { + id: testDirectChats[0]._id, + }; + + const directChatsMessagesByChatIdPayload = + await directChatsMessagesByChatIDResolver?.({}, args, {}); + + const directChatMessagesByChatId = await DirectChatMessage.find({ + directChatMessageBelongsTo: testDirectChats[0]._id, + }).lean(); + + expect(directChatsMessagesByChatIdPayload).toEqual( + directChatMessagesByChatId + ); + }); +}); diff --git a/__tests__/resolvers/Query/event.spec.ts b/__tests__/resolvers/Query/event.spec.ts new file mode 100644 index 0000000000..70ef334a79 --- /dev/null +++ b/__tests__/resolvers/Query/event.spec.ts @@ -0,0 +1,121 @@ +import "dotenv/config"; +import { event as eventResolver } from "../../../src/lib/resolvers/Query/event"; +import { connect, disconnect } from "../../../src/db"; +import { EVENT_NOT_FOUND } from "../../../src/constants"; +import { + User, + Organization, + Event, + Task, + Interface_Event, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Document, Types } from "mongoose"; +import { QueryEventArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + testEvent = await Event.create({ + creator: testUser._id, + registrants: [{ userId: testUser._id, user: testUser._id }], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + eventAdmin: [testEvent._id], + }, + } + ); + + const testTask = await Task.create({ + title: "title", + event: testEvent._id, + creator: testUser._id, + }); + + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $push: { + tasks: testTask._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> event", () => { + it(`throws NotFoundError if no event exists with _id === args.id + and event.status === 'ACTIVE'`, async () => { + try { + const args: QueryEventArgs = { + id: Types.ObjectId().toString(), + }; + + await eventResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`returns event object with populated fields creator, tasks, admins`, async () => { + const args: QueryEventArgs = { + id: testEvent?._id, + }; + + const eventPayload = await eventResolver?.({}, args, {}); + + const event = await Event.findOne({ + _id: testEvent._id, + }) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventPayload).toEqual(event); + }); +}); diff --git a/__tests__/resolvers/Query/events.spec.ts b/__tests__/resolvers/Query/events.spec.ts new file mode 100644 index 0000000000..26dcd5b02b --- /dev/null +++ b/__tests__/resolvers/Query/events.spec.ts @@ -0,0 +1,642 @@ +import "dotenv/config"; +import { events as eventsResolver } from "../../../src/lib/resolvers/Query/events"; +import { Event, User, Organization, Task } from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { nanoid } from "nanoid"; +import { + QueryEventsArgs, + EventOrderByInput, +} from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + const testEvents = await Event.insertMany([ + { + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: `title${nanoid()}`, + description: `description${nanoid()}`, + allDay: true, + startDate: new Date().toString(), + endDate: new Date().toString(), + startTime: new Date().toString(), + endTime: new Date().toString(), + recurrance: "ONCE", + location: `location${nanoid()}`, + }, + { + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: `title${nanoid()}`, + description: `description${nanoid()}`, + allDay: false, + startDate: new Date().toString(), + endDate: new Date().toString(), + startTime: new Date().toString(), + endTime: new Date().toString(), + recurrance: "DAILY", + location: `location${nanoid()}`, + }, + ]); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + createdEvents: [testEvents[0]._id, testEvents[1]._id], + registeredEvents: [testEvents[0]._id, testEvents[1]._id], + eventAdmin: [testEvents[0]._id, testEvents[1]._id], + }, + } + ); + + const testTask = await Task.create({ + title: "title", + event: testEvents[0]._id, + creator: testUser._id, + }); + + await Event.updateOne( + { + _id: testEvents[0]._id, + }, + { + $set: { + tasks: [testTask._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> events", () => { + it(`returns list of all existing events sorted by ascending order of event._id + if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.IdAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event._id + if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.IdDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.title + if args.orderBy === 'title_ASC'`, async () => { + const sort = { + title: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.TitleAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.title + if args.orderBy === 'title_DESC'`, async () => { + const sort = { + title: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.TitleDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.description + if args.orderBy === 'description_ASC'`, async () => { + const sort = { + description: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.DescriptionAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.description + if args.orderBy === 'description_DESC'`, async () => { + const sort = { + description: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.DescriptionDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.startDate + if args.orderBy === 'startDate_ASC'`, async () => { + const sort = { + startDate: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.StartDateAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.startDate + if args.orderBy === 'startDate_DESC'`, async () => { + const sort = { + startDate: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.StartDateDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.endDate + if args.orderBy === 'endDate_ASC'`, async () => { + const sort = { + endDate: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.EndDateAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.endDate + if args.orderBy === 'endDate_DESC'`, async () => { + const sort = { + endDate: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.EndDateDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.allDay + if args.orderBy === 'allDay_ASC'`, async () => { + const sort = { + allDay: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.AllDayAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.allDay + if args.orderBy === 'allDay_DESC'`, async () => { + const sort = { + allDay: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.AllDayDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.startTime + if args.orderBy === 'startTime_ASC'`, async () => { + const sort = { + startTime: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.StartTimeAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.startTime + if args.orderBy === 'startTime_DESC'`, async () => { + const sort = { + startTime: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.StartTimeDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.endTime + if args.orderBy === 'endTime_ASC'`, async () => { + const sort = { + endTime: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.EndTimeAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.endTime + if args.orderBy === 'endTime_DESC'`, async () => { + const sort = { + endTime: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.EndTimeDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.recurrance + if args.orderBy === 'recurrance_ASC'`, async () => { + const sort = { + recurrance: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.RecurranceAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.recurrance + if args.orderBy === 'recurrance_DESC'`, async () => { + const sort = { + recurrance: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.RecurranceDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by ascending order of event.location + if args.orderBy === 'location_ASC'`, async () => { + const sort = { + location: 1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.LocationAsc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.location + if args.orderBy === 'location_DESC'`, async () => { + const sort = { + location: -1, + }; + + const args: QueryEventsArgs = { + orderBy: EventOrderByInput.LocationDesc, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events sorted by descending order of event.location + if args.orderBy === undefined`, async () => { + const sort = { + location: -1, + }; + + const args: QueryEventsArgs = { + orderBy: undefined, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); + + it(`returns list of all existing events without sorting if args.orderBy === null`, async () => { + const sort = {}; + + const args: QueryEventsArgs = { + orderBy: null, + }; + + const eventsPayload = await eventsResolver?.({}, args, {}); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsPayload).toEqual(events); + }); +}); diff --git a/__tests__/resolvers/Query/eventsByOrganization.spec.ts b/__tests__/resolvers/Query/eventsByOrganization.spec.ts new file mode 100644 index 0000000000..8b9269a00d --- /dev/null +++ b/__tests__/resolvers/Query/eventsByOrganization.spec.ts @@ -0,0 +1,784 @@ +import "dotenv/config"; +import { eventsByOrganization as eventsByOrganizationResolver } from "../../../src/lib/resolvers/Query/eventsByOrganization"; +import { + Event, + User, + Organization, + Task, + Interface_Organization, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { nanoid } from "nanoid"; +import { + QueryEventsByOrganizationArgs, + EventOrderByInput, +} from "../../../src/generated/graphqlCodegen"; +import { Document } from "mongoose"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + const testEvents = await Event.insertMany([ + { + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: `title${nanoid()}`, + description: `description${nanoid()}`, + allDay: true, + startDate: new Date().toString(), + endDate: new Date().toString(), + startTime: new Date().toString(), + endTime: new Date().toString(), + recurrance: "ONCE", + location: `location${nanoid()}`, + }, + { + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: `title${nanoid()}`, + description: `description${nanoid()}`, + allDay: true, + startDate: new Date().toString(), + endDate: new Date().toString(), + startTime: new Date().toString(), + endTime: new Date().toString(), + recurrance: "ONCE", + location: `location${nanoid()}`, + }, + ]); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + createdEvents: [testEvents[0]._id, testEvents[1]._id], + registeredEvents: [testEvents[0]._id, testEvents[1]._id], + eventAdmin: [testEvents[0]._id, testEvents[1]._id], + }, + } + ); + + const testTask = await Task.create({ + title: "title", + event: testEvents[0]._id, + creator: testUser._id, + }); + + await Event.updateOne( + { + _id: testEvents[0]._id, + }, + { + $set: { + tasks: [testTask._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> eventsByOrganization", () => { + it(`returns list of all existing events sorted by ascending order of event._id + if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.IdAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event._id + if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.IdDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.title + if args.orderBy === 'title_ASC'`, async () => { + const sort = { + title: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.TitleAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.title + if args.orderBy === 'title_DESC'`, async () => { + const sort = { + title: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.TitleDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.description + if args.orderBy === 'description_ASC'`, async () => { + const sort = { + description: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.DescriptionAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.description + if args.orderBy === 'description_DESC'`, async () => { + const sort = { + description: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.DescriptionDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.startDate + if args.orderBy === 'startDate_ASC'`, async () => { + const sort = { + startDate: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.StartDateAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.startDate + if args.orderBy === 'startDate_DESC'`, async () => { + const sort = { + startDate: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.StartDateDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.endDate + if args.orderBy === 'endDate_ASC'`, async () => { + const sort = { + endDate: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.EndDateAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.endDate + if args.orderBy === 'endDate_DESC'`, async () => { + const sort = { + endDate: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.EndDateDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.allDay + if args.orderBy === 'allDay_ASC'`, async () => { + const sort = { + allDay: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.AllDayAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.allDay + if args.orderBy === 'allDay_DESC'`, async () => { + const sort = { + allDay: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.AllDayDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.startTime + if args.orderBy === 'startTime_ASC'`, async () => { + const sort = { + startTime: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.StartTimeAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.startTime + if args.orderBy === 'startTime_DESC'`, async () => { + const sort = { + startTime: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.StartTimeDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.endTime + if args.orderBy === 'endTime_ASC'`, async () => { + const sort = { + endTime: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.EndTimeAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.endTime + if args.orderBy === 'endTime_DESC'`, async () => { + const sort = { + endTime: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.EndTimeDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.recurrance + if args.orderBy === 'recurrance_ASC'`, async () => { + const sort = { + recurrance: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.RecurranceAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.recurrance + if args.orderBy === 'recurrance_DESC'`, async () => { + const sort = { + recurrance: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.RecurranceDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by ascending order of event.location + if args.orderBy === 'location_ASC'`, async () => { + const sort = { + location: 1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.LocationAsc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.location + if args.orderBy === 'location_DESC'`, async () => { + const sort = { + location: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: EventOrderByInput.LocationDesc, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events sorted by descending order of event.location + if args.orderBy === undefined`, async () => { + const sort = { + location: -1, + }; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: undefined, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); + + it(`returns list of all existing events without sorting if args.orderBy === null`, async () => { + const sort = {}; + + const args: QueryEventsByOrganizationArgs = { + id: testOrganization._id, + orderBy: null, + }; + + const eventsByOrganizationPayload = await eventsByOrganizationResolver?.( + {}, + args, + {} + ); + + const eventsByOrganization = await Event.find({ + organization: testOrganization._id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + expect(eventsByOrganizationPayload).toEqual(eventsByOrganization); + }); +}); diff --git a/__tests__/resolvers/Query/getDonationById.spec.ts b/__tests__/resolvers/Query/getDonationById.spec.ts new file mode 100644 index 0000000000..37d8a7c423 --- /dev/null +++ b/__tests__/resolvers/Query/getDonationById.spec.ts @@ -0,0 +1,78 @@ +import "dotenv/config"; +import { + User, + Organization, + Donation, + Interface_Donation, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { getDonationById as getDonationByIdResolver } from "../../../src/lib/resolvers/Query/getDonationById"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; +import { QueryGetDonationByIdArgs } from "../../../src/generated/graphqlCodegen"; +import { Document } from "mongoose"; + +let testDonation: Interface_Donation & Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + testDonation = await Donation.create({ + amount: 1, + nameOfOrg: testOrganization.name, + nameOfUser: `${testUser.firstName} ${testUser.lastName}`, + orgId: testOrganization._id, + payPalId: "payPalId", + userId: testUser._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> getDonationById", () => { + it(`returns the donation with _id === args.id`, async () => { + const args: QueryGetDonationByIdArgs = { + id: testDonation._id, + }; + + const getDonationByIdPayload = await getDonationByIdResolver?.( + {}, + args, + {} + ); + + expect(getDonationByIdPayload).toEqual(testDonation.toObject()); + }); +}); diff --git a/__tests__/resolvers/Query/getDonationByOrgId.spec.ts b/__tests__/resolvers/Query/getDonationByOrgId.spec.ts new file mode 100644 index 0000000000..e425b68df7 --- /dev/null +++ b/__tests__/resolvers/Query/getDonationByOrgId.spec.ts @@ -0,0 +1,83 @@ +import "dotenv/config"; +import { + User, + Organization, + Donation, + Interface_Organization, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { getDonationByOrgId as getDonationByOrgIdResolver } from "../../../src/lib/resolvers/Query/getDonationByOrgId"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; +import { QueryGetDonationByOrgIdArgs } from "../../../src/generated/graphqlCodegen"; +import { Document } from "mongoose"; + +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + await Donation.create({ + amount: 1, + nameOfOrg: testOrganization.name, + nameOfUser: `${testUser.firstName} ${testUser.lastName}`, + orgId: testOrganization._id, + payPalId: "payPalId", + userId: testUser._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> getDonationByOrgId", () => { + it(`returns a list of all donations with orgId === args.orgId`, async () => { + const args: QueryGetDonationByOrgIdArgs = { + orgId: testOrganization._id, + }; + + const getDonationByOrgIdPayload = await getDonationByOrgIdResolver?.( + {}, + args, + {} + ); + + const donationsByOrganization = await Donation.find({ + orgId: testOrganization._id, + }).lean(); + + expect(getDonationByOrgIdPayload).toEqual(donationsByOrganization); + }); +}); diff --git a/__tests__/resolvers/Query/getDonations.spec.ts b/__tests__/resolvers/Query/getDonations.spec.ts new file mode 100644 index 0000000000..934df3bf6b --- /dev/null +++ b/__tests__/resolvers/Query/getDonations.spec.ts @@ -0,0 +1,63 @@ +import "dotenv/config"; +import { User, Organization, Donation } from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { getDonations as getDonationsResolver } from "../../../src/lib/resolvers/Query/getDonations"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + await Donation.create({ + amount: 1, + nameOfOrg: testOrganization.name, + nameOfUser: `${testUser.firstName} ${testUser.lastName}`, + orgId: testOrganization._id, + payPalId: "payPalId", + userId: testUser._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Mutation -> getDonations", () => { + it(`returns a list of all existing donations`, async () => { + const getDonationsPayload = await getDonationsResolver?.({}, {}, {}); + + const donations = await Donation.find().lean(); + + expect(getDonationsPayload).toEqual(donations); + }); +}); diff --git a/__tests__/resolvers/Query/getPlugins.spec.ts b/__tests__/resolvers/Query/getPlugins.spec.ts new file mode 100644 index 0000000000..86a74be665 --- /dev/null +++ b/__tests__/resolvers/Query/getPlugins.spec.ts @@ -0,0 +1,49 @@ +import "dotenv/config"; +import { getPlugins as getPluginsResolver } from "../../../src/lib/resolvers/Query/getPlugins"; +import { connect, disconnect } from "../../../src/db"; +import { Organization, Plugin, User } from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await Plugin.create({ + pluginName: "pluginName", + pluginCreatedBy: `${testUser.firstName} ${testUser.lastName}`, + pluginDesc: "pluginDesc", + pluginInstallStatus: true, + installedOrgs: [testOrganization._id], + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> getPlugins", () => { + it(`returns list of all existing plugins`, async () => { + const getPluginsPayload = await getPluginsResolver?.({}, {}, {}); + + const plugins = await Plugin.find().lean(); + + expect(getPluginsPayload).toEqual(plugins); + }); +}); diff --git a/__tests__/resolvers/Query/getlanguage.spec.ts b/__tests__/resolvers/Query/getlanguage.spec.ts new file mode 100644 index 0000000000..d484ebe962 --- /dev/null +++ b/__tests__/resolvers/Query/getlanguage.spec.ts @@ -0,0 +1,83 @@ +import "dotenv/config"; +import { getlanguage as getLanguageResolver } from "../../../src/lib/resolvers/Query/getlanguage"; +import { connect, disconnect } from "../../../src/db"; +import { Interface_Language, Language } from "../../../src/lib/models"; +import { Document } from "mongoose"; +import { QueryGetlanguageArgs } from "../../../src/generated/graphqlCodegen"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testLanguages: (Interface_Language & + Document)[]; + +const enValue = `en ${nanoid().toLowerCase()}`; +const deValue = `de ${nanoid().toLowerCase()}`; +const frValue = `fr ${nanoid().toLowerCase()}`; + +beforeAll(async () => { + await connect(); + + testLanguages = await Language.insertMany([ + { + en: enValue, + translation: [ + { + lang_code: enValue, + value: "value1", + verified: true, + }, + ], + }, + { + en: deValue, + translation: [ + { + lang_code: enValue, + value: "value2", + verified: false, + }, + ], + }, + { + en: frValue, + translation: [ + { + lang_code: deValue, + value: "value3", + verfied: true, + }, + ], + }, + ]); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> getLanguage", () => { + it(`returns list of all languages where language.translation.lang_code === args.lang_code`, async () => { + const args: QueryGetlanguageArgs = { + lang_code: testLanguages[0].en, + }; + + const getLanguagePayload = await getLanguageResolver?.({}, args, {}); + + expect(getLanguagePayload).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + lang_code: enValue, + en_value: enValue, + translation: "value1", + verified: true, + }), + expect.objectContaining({ + lang_code: enValue, + en_value: deValue, + translation: "value2", + verified: false, + }), + ]) + ); + }); +}); diff --git a/__tests__/resolvers/Query/groupChatMessages.spec.ts b/__tests__/resolvers/Query/groupChatMessages.spec.ts new file mode 100644 index 0000000000..01e234ec6b --- /dev/null +++ b/__tests__/resolvers/Query/groupChatMessages.spec.ts @@ -0,0 +1,77 @@ +import "dotenv/config"; +import { groupChatMessages as groupChatMessagesResolver } from "../../../src/lib/resolvers/Query/groupChatMessages"; +import { connect, disconnect } from "../../../src/db"; +import { + GroupChat, + GroupChatMessage, + Organization, + User, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const groupChat = await GroupChat.create({ + title: "title", + users: [testUser._id], + creator: testUser._id, + organization: testOrganization._id, + }); + + await GroupChatMessage.create({ + groupChatMessageBelongsTo: groupChat._id, + sender: testUser._id, + messageContent: "messageContent", + createdAt: new Date().toString(), + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> groupChatMessages", () => { + it(`returns list of all existing groupChatMessages`, async () => { + const groupChatMessagesPayload = await groupChatMessagesResolver?.( + {}, + {}, + {} + ); + + const groupChatMessages = await GroupChatMessage.find().lean(); + + expect(groupChatMessagesPayload).toEqual(groupChatMessages); + }); +}); diff --git a/__tests__/resolvers/Query/groupChats.spec.ts b/__tests__/resolvers/Query/groupChats.spec.ts new file mode 100644 index 0000000000..8aaab9271a --- /dev/null +++ b/__tests__/resolvers/Query/groupChats.spec.ts @@ -0,0 +1,61 @@ +import "dotenv/config"; +import { groupChats as groupChatsResolver } from "../../../src/lib/resolvers/Query/groupChats"; +import { connect, disconnect } from "../../../src/db"; +import { GroupChat, Organization, User } from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + await GroupChat.create({ + title: "title", + users: [testUser._id], + creator: testUser._id, + organization: testOrganization._id, + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> groupChats", () => { + it(`returns list of all existing groupChats`, async () => { + const groupChatsPayload = await groupChatsResolver?.({}, {}, {}); + + const groupChats = await GroupChat.find().lean(); + + expect(groupChatsPayload).toEqual(groupChats); + }); +}); diff --git a/__tests__/resolvers/Query/groups.spec.ts b/__tests__/resolvers/Query/groups.spec.ts new file mode 100644 index 0000000000..95ec21367a --- /dev/null +++ b/__tests__/resolvers/Query/groups.spec.ts @@ -0,0 +1,60 @@ +import "dotenv/config"; +import { groups as groupsResolver } from "../../../src/lib/resolvers/Query/groups"; +import { connect, disconnect } from "../../../src/db"; +import { User, Organization, Group } from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + await Group.create({ + title: "title", + organization: testOrganization._id, + admins: [testUser._id], + }); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> groups", () => { + it(`returns list of all existing groups`, async () => { + const groupsPayload = await groupsResolver?.({}, {}, {}); + + const groups = await Group.find().lean(); + + expect(groupsPayload).toEqual(groups); + }); +}); diff --git a/__tests__/resolvers/Query/isUserRegister.spec.ts b/__tests__/resolvers/Query/isUserRegister.spec.ts new file mode 100644 index 0000000000..8cc20a66d8 --- /dev/null +++ b/__tests__/resolvers/Query/isUserRegister.spec.ts @@ -0,0 +1,228 @@ +import "dotenv/config"; +import { isUserRegister as isUserRegisterResolver } from "../../../src/lib/resolvers/Query/isUserRegister"; +import { + User, + Organization, + Event, + Interface_Event, + Task, + Interface_User, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { nanoid } from "nanoid"; +import { Document, Types } from "mongoose"; +import { QueryIsUserRegisterArgs } from "../../../src/generated/graphqlCodegen"; +import { EVENT_NOT_FOUND } from "../../../src/constants"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + testEvent = await Event.create({ + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + eventAdmin: [testEvent._id], + }, + } + ); + + const testTask = await Task.create({ + title: "title", + event: testEvent._id, + creator: testUser._id, + }); + + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $push: { + tasks: testTask._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> isUserRegister", () => { + it(`throws NotFoundError if no event exists with _id === args.eventId + and event.status === 'ACTIVE'`, async () => { + try { + const args: QueryIsUserRegisterArgs = { + eventId: Types.ObjectId().toString(), + }; + + const context = {}; + + await isUserRegisterResolver?.({}, args, context); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it(`returns object with event object and isRegistered === false + if user with _id === context.userId is not a registrant to the event and + user's registrant status === 'ACTIVE'`, async () => { + const args: QueryIsUserRegisterArgs = { + eventId: testEvent.id, + }; + + const context = { + userId: Types.ObjectId().toString(), + }; + + const event = await Event.findOne({ + _id: testEvent._id, + status: "ACTIVE", + }) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const isUserRegisterPayload = await isUserRegisterResolver?.( + {}, + args, + context + ); + + expect(isUserRegisterPayload).toEqual({ + event, + isRegistered: false, + }); + }); + + it(`returns object with event object and isRegistered === false + if user with _id === context.userId is a registrant to the event and + user's registrant status !== 'ACTIVE'`, async () => { + const args: QueryIsUserRegisterArgs = { + eventId: testEvent.id, + }; + + const context = { + userId: testUser.id, + }; + + const event = await Event.findOneAndUpdate( + { + _id: testEvent._id, + "registrants.userId": testUser._id, + }, + { + $set: { + "registrants.$.status": "BLOCKED", + }, + }, + { + new: true, + } + ) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const isUserRegisterPayload = await isUserRegisterResolver?.( + {}, + args, + context + ); + + expect(isUserRegisterPayload).toEqual({ + event, + isRegistered: false, + }); + }); + + it(`returns object with event object and isRegistered === true + if user with _id === context.userId is a registrant to the event and + user's registrant status === 'ACTIVE'`, async () => { + const args: QueryIsUserRegisterArgs = { + eventId: testEvent.id, + }; + + const context = { + userId: testUser.id, + }; + + const event = await Event.findOneAndUpdate( + { + _id: testEvent._id, + "registrants.userId": testUser._id, + }, + { + $set: { + "registrants.$.status": "ACTIVE", + }, + }, + { + new: true, + } + ) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const isUserRegisterPayload = await isUserRegisterResolver?.( + {}, + args, + context + ); + + expect(isUserRegisterPayload).toEqual({ + event, + isRegistered: true, + }); + }); +}); diff --git a/__tests__/resolvers/Query/me.spec.ts b/__tests__/resolvers/Query/me.spec.ts new file mode 100644 index 0000000000..3042144b75 --- /dev/null +++ b/__tests__/resolvers/Query/me.spec.ts @@ -0,0 +1,117 @@ +import "dotenv/config"; +import { me as meResolver } from "../../../src/lib/resolvers/Query/me"; +import { connect, disconnect } from "../../../src/db"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { + Interface_User, + User, + Organization, + Event, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Document, Types } from "mongoose"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: (Interface_User & Document) | null; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testEvent = await Event.create({ + creator: testUser._id, + registrants: [{ userId: testUser._id, user: testUser._id }], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + eventAdmin: [testEvent._id], + }, + } + ); +}); + +afterAll(async () => { + disconnect(); +}); + +describe("resolvers -> Query -> me", () => { + it("throws NotFoundError if no user exists with _id === context.userId", async () => { + try { + const context = { + userId: Types.ObjectId().toString(), + }; + + await meResolver?.({}, {}, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`returns user object with populated fields createdOrganizations + , createdEvents, joinedOrganizations, registeredEvents, eventAdmin, + adminFor`, async () => { + const context = { + userId: testUser!._id, + }; + + const mePayload = await meResolver?.({}, {}, context); + + const user = await User.findOne({ + _id: testUser!._id, + }) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(mePayload).toEqual(user); + }); +}); diff --git a/__tests__/resolvers/Query/myLanguage.spec.ts b/__tests__/resolvers/Query/myLanguage.spec.ts new file mode 100644 index 0000000000..8196d13c83 --- /dev/null +++ b/__tests__/resolvers/Query/myLanguage.spec.ts @@ -0,0 +1,48 @@ +import "dotenv/config"; +import { myLanguage as myLanguageResolver } from "../../../src/lib/resolvers/Query/myLanguage"; +import { connect, disconnect } from "../../../src/db"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { User } from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Types } from "mongoose"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> myLanguage", () => { + it("throws NotFoundError if no user exists with _id === context.userId", async () => { + try { + const context = { + userId: Types.ObjectId().toString(), + }; + + await myLanguageResolver?.({}, {}, context); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`returns current user's appLanguageCode`, async () => { + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const context = { + userId: testUser?._id, + }; + + const appLanguageCodePayload = await myLanguageResolver?.({}, {}, context); + + expect(appLanguageCodePayload).toEqual(testUser?.appLanguageCode); + }); +}); diff --git a/__tests__/resolvers/Query/organizations.spec.ts b/__tests__/resolvers/Query/organizations.spec.ts new file mode 100644 index 0000000000..e65e0cad0e --- /dev/null +++ b/__tests__/resolvers/Query/organizations.spec.ts @@ -0,0 +1,298 @@ +import "dotenv/config"; +import { organizations as organizationsResolver } from "../../../src/lib/resolvers/Query/organizations"; +import { ORGANIZATION_NOT_FOUND } from "../../../src/constants"; +import { + Interface_Organization, + Organization, + User, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { + QueryOrganizationsArgs, + OrganizationOrderByInput, +} from "../../../src/generated/graphqlCodegen"; +import { Document, Types } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization1: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganizations = await Organization.insertMany([ + { + name: `name${nanoid()}`, + description: `description${nanoid()}`, + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + apiUrl: `apiUrl${nanoid()}`, + }, + { + name: `name${nanoid()}`, + description: `description${nanoid()}`, + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + apiUrl: `apiUrl${nanoid()}`, + }, + ]); + + testOrganization1 = testOrganizations[0]; + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [ + testOrganizations[0]._id, + testOrganizations[1]._id, + ], + adminFor: [testOrganizations[0]._id, testOrganizations[1]._id], + joinedOrganizations: [ + testOrganizations[0]._id, + testOrganizations[1]._id, + ], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> organizations", () => { + it("throws NotFoundError if no organization exists with _id === args.id", async () => { + try { + const args: QueryOrganizationsArgs = { + id: Types.ObjectId().toString(), + }; + + await organizationsResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(ORGANIZATION_NOT_FOUND); + } + }); + + it("returns organization object with _id === args.id", async () => { + const args: QueryOrganizationsArgs = { + id: testOrganization1._id, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + expect(organizationsPayload).toEqual([testOrganization1.toObject()]); + }); + + it(`returns list of at most 100 organizations sorted by ascending order of + organization._id if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.IdAsc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by descending order of + organization._id if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.IdDesc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by ascending order of + organization.name if args.orderBy === 'name_ASC'`, async () => { + const sort = { + name: 1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.NameAsc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by descending order of + organization.name if args.orderBy === 'name_DESC'`, async () => { + const sort = { + name: -1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.NameDesc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by ascending order of + organization.description if args.orderBy === 'description_ASC'`, async () => { + const sort = { + description: 1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.DescriptionAsc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by descending order of + organization.description if args.orderBy === 'description_DESC'`, async () => { + const sort = { + description: -1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.DescriptionDesc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by ascending order of + organization.apiUrl if args.orderBy === 'apiUrl_ASC'`, async () => { + const sort = { + apiUrl: 1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.ApiUrlAsc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by descending order of + organization.apiUrl if args.orderBy === 'apiUrl_DESC'`, async () => { + const sort = { + apiUrl: -1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: OrganizationOrderByInput.ApiUrlDesc, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations sorted by descending order of + organization.apiUrl if args.orderBy === undefined`, async () => { + const sort = { + apiUrl: -1, + }; + + const args: QueryOrganizationsArgs = { + orderBy: undefined, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); + + it(`returns list of at most 100 organizations`, async () => { + const sort = {}; + + const args: QueryOrganizationsArgs = { + orderBy: null, + }; + + const organizationsPayload = await organizationsResolver?.({}, args, {}); + + const organizations = await Organization.find() + .sort(sort) + .limit(100) + .lean(); + + expect(organizationsPayload).toEqual(organizations); + }); +}); diff --git a/__tests__/resolvers/Query/organizationsConnection.spec.ts b/__tests__/resolvers/Query/organizationsConnection.spec.ts new file mode 100644 index 0000000000..afc8f82ac8 --- /dev/null +++ b/__tests__/resolvers/Query/organizationsConnection.spec.ts @@ -0,0 +1,453 @@ +import "dotenv/config"; +import { organizationsConnection as organizationsConnectionResolver } from "../../../src/lib/resolvers/Query/organizationsConnection"; +import { + Interface_Organization, + Organization, + User, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { + OrganizationOrderByInput, + QueryOrganizationsConnectionArgs, +} from "../../../src/generated/graphqlCodegen"; +import { nanoid } from "nanoid"; +import { Document } from "mongoose"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganizations: (Interface_Organization & + Document)[]; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganizations = await Organization.insertMany([ + { + name: `name${nanoid()}`, + description: `description${nanoid()}`, + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + apiUrl: `apiUrl${nanoid()}`, + visibleInSearch: true, + }, + { + name: `name${nanoid()}`, + description: `description${nanoid()}`, + isPublic: false, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + apiUrl: `apiUrl${nanoid()}`, + visibleInSearch: false, + }, + { + name: `name${nanoid()}`, + description: `description${nanoid()}`, + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + apiUrl: `apiUrl${nanoid()}`, + visibleInSearch: true, + }, + ]); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [ + testOrganizations[0]._id, + testOrganizations[1]._id, + testOrganizations[2]._id, + ], + adminFor: [ + testOrganizations[0]._id, + testOrganizations[1]._id, + testOrganizations[2]._id, + ], + joinedOrganizations: [ + testOrganizations[0]._id, + testOrganizations[1]._id, + testOrganizations[2]._id, + ], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> organizationsConnection", () => { + it(`returns paginated list of all existing organizations without any filtering and sorting'`, async () => { + const args: QueryOrganizationsConnectionArgs = { + where: null, + orderBy: null, + first: 2, + skip: 1, + }; + + const organizations = await Organization.find().limit(2).skip(1).lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations filtered by args.where === + { id: testOrganizations[1]._id, name: testOrganizations[1].name, + description: testOrganizations[1].description, apiUrl: testOrganizations[1].apiUrl, + visibleInSearch: testOrganizations[1].visibleInSearch, isPublic: testOrganizations[1].isPublic } + and sorted by ascending order of organization._id if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const where = { + _id: testOrganizations[1]._id, + name: testOrganizations[1].name, + description: testOrganizations[1].description, + apiUrl: testOrganizations[1].apiUrl, + visibleInSearch: testOrganizations[1].visibleInSearch, + isPublic: testOrganizations[1].isPublic, + }; + + const args: QueryOrganizationsConnectionArgs = { + first: 2, + skip: 1, + where: { + id: testOrganizations[1].id, + name: testOrganizations[1].name, + description: testOrganizations[1].description, + apiUrl: testOrganizations[1].apiUrl, + visibleInSearch: testOrganizations[1].visibleInSearch, + isPublic: testOrganizations[1].isPublic, + }, + orderBy: OrganizationOrderByInput.IdAsc, + }; + + const organizations = await Organization.find(where) + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations filtered by args.where === + { id_not: testOrganizations[0]._id, name_not: testOrganizations[0].name, + description_not: testOrganizations[0].description, apiUrl_not: testOrganizations[0].apiUrl } and + sorted by descending order of organization._id if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const where = { + _id: { + $ne: testOrganizations[0]._id, + }, + name: { + $ne: testOrganizations[0].name, + }, + description: { + $ne: testOrganizations[0].description, + }, + apiUrl: { + $ne: testOrganizations[0].apiUrl, + }, + }; + + const args: QueryOrganizationsConnectionArgs = { + first: 2, + skip: 1, + where: { + id_not: testOrganizations[0].id, + name_not: testOrganizations[0].name, + description_not: testOrganizations[0].description, + apiUrl_not: testOrganizations[0].apiUrl, + }, + orderBy: OrganizationOrderByInput.IdDesc, + }; + + const organizations = await Organization.find(where) + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations filtered by args.where === + { id_in: [testOrganizations[1]._id], name_in: [testOrganizations[1].name], + description_in: [testOrganizations[1].description], apiUrl_in: [testOrganizations[1].apiUrl] } and + sorted by ascending order of organization.name if args.orderBy === 'name_ASC'`, async () => { + const sort = { + name: 1, + }; + + const where = { + _id: { + $in: [testOrganizations[1]._id], + }, + name: { + $in: [testOrganizations[1].name], + }, + description: { + $in: [testOrganizations[1].description], + }, + apiUrl: { + $in: [testOrganizations[1].apiUrl], + }, + }; + + const args: QueryOrganizationsConnectionArgs = { + first: 2, + skip: 1, + where: { + id_in: [testOrganizations[1]._id], + name_in: [testOrganizations[1].name], + description_in: [testOrganizations[1].description], + apiUrl_in: [testOrganizations[1].apiUrl!], + }, + orderBy: OrganizationOrderByInput.NameAsc, + }; + + const organizations = await Organization.find(where) + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations filtered by args.where === + { id_not_in: [testOrganizations[0]._id], name_not_in: [testOrganizations[0].name], + description_not_in: [testOrganizations[0].description], apiUrl_not_in: [testOrganizations[0].apiUrl] } and + sorted by descending order of organization.name if args.orderBy === 'name_DESC'`, async () => { + const sort = { + name: -1, + }; + + const where = { + _id: { + $nin: [testOrganizations[0]._id], + }, + name: { + $nin: [testOrganizations[0].name], + }, + description: { + $nin: [testOrganizations[0].description], + }, + apiUrl: { + $nin: [testOrganizations[0].apiUrl], + }, + }; + + const args: QueryOrganizationsConnectionArgs = { + first: 2, + skip: 1, + where: { + id_not_in: [testOrganizations[0]._id], + name_not_in: [testOrganizations[0].name], + description_not_in: [testOrganizations[0].description], + apiUrl_not_in: [testOrganizations[0].apiUrl!], + }, + orderBy: OrganizationOrderByInput.NameDesc, + }; + + const organizations = await Organization.find(where) + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations filtered by args.where === + { name_contains: testOrganizations[1].name, description_contains: testOrganizations[1].description, + apiUrl_contains: testOrganizations[1].apiUrl } and sorted by ascending order of + organization.description if args.orderBy === 'description_ASC'`, async () => { + const sort = { + description: 1, + }; + + const where = { + name: { + $regex: testOrganizations[1].name, + $options: "i", + }, + description: { + $regex: testOrganizations[1].description, + $options: "i", + }, + apiUrl: { + $regex: testOrganizations[1].apiUrl, + $options: "i", + }, + }; + + const args: QueryOrganizationsConnectionArgs = { + first: 2, + skip: 1, + where: { + name_contains: testOrganizations[1].name, + description_contains: testOrganizations[1].description, + apiUrl_contains: testOrganizations[1].apiUrl, + }, + orderBy: OrganizationOrderByInput.DescriptionAsc, + }; + + const organizations = await Organization.find(where) + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations filtered by args.where === + { name_starts_with: testOrganizations[1].name, description_starts_with: testOrganizations[1].description, + apiUrl_starts_with: testOrganizations[1].apiUrl } and sorted by descending order of + organization.description if args.orderBy === 'description_DESC'`, async () => { + const sort = { + description: -1, + }; + + const where = { + name: new RegExp("^" + testOrganizations[1].name), + description: new RegExp("^" + testOrganizations[1].description), + apiUrl: new RegExp("^" + testOrganizations[1].apiUrl), + }; + + const args: QueryOrganizationsConnectionArgs = { + first: 2, + skip: 1, + where: { + name_starts_with: testOrganizations[1].name, + description_starts_with: testOrganizations[1].description, + apiUrl_starts_with: testOrganizations[1].apiUrl, + }, + orderBy: OrganizationOrderByInput.DescriptionDesc, + }; + + const organizations = await Organization.find(where) + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations sorted by ascending order of + organization.apiUrl if args.orderBy === 'apiUrl_ASC'`, async () => { + const sort = { + apiUrl: 1, + }; + + const args: QueryOrganizationsConnectionArgs = { + where: null, + first: 2, + skip: 1, + orderBy: OrganizationOrderByInput.ApiUrlAsc, + }; + + const organizations = await Organization.find() + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations sorted by descending order of + organization.apiUrl if args.orderBy === 'apiUrl_DESC'`, async () => { + const sort = { + apiUrl: -1, + }; + + const args: QueryOrganizationsConnectionArgs = { + where: null, + first: 2, + skip: 1, + orderBy: OrganizationOrderByInput.ApiUrlDesc, + }; + + const organizations = await Organization.find() + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); + + it(`returns paginated list of all existing organizations sorted by descending order of + organization.apiUrl if args.orderBy === undefined`, async () => { + const sort = { + apiUrl: -1, + }; + + const args: QueryOrganizationsConnectionArgs = { + where: null, + first: 2, + skip: 1, + orderBy: undefined, + }; + + const organizations = await Organization.find() + .limit(2) + .skip(1) + .sort(sort) + .lean(); + + const organizationsConnectionPayload = + await organizationsConnectionResolver?.({}, args, {}); + + expect(organizationsConnectionPayload).toEqual(organizations); + }); +}); diff --git a/__tests__/resolvers/Query/organizationsMemberConnection.spec.ts b/__tests__/resolvers/Query/organizationsMemberConnection.spec.ts new file mode 100644 index 0000000000..3762162c09 --- /dev/null +++ b/__tests__/resolvers/Query/organizationsMemberConnection.spec.ts @@ -0,0 +1,576 @@ +import "dotenv/config"; +import { organizationsMemberConnection as organizationsMemberConnectionResolver } from "../../../src/lib/resolvers/Query/organizationsMemberConnection"; +import { + Interface_Organization, + Interface_User, + Organization, + User, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { QueryOrganizationsMemberConnectionArgs } from "../../../src/generated/graphqlCodegen"; +import { Document, Types } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `1firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid().toLowerCase()}`, + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `2firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid().toLowerCase()}`, + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `3firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid().toLowerCase()}`, + }, + ]); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id, testUsers[1]._id, testUsers[2]._id], + members: [testUsers[0]._id, testUsers[1]._id, testUsers[2]._id], + apiUrl: "apiUrl", + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + await User.updateOne( + { + _id: testUsers[1].id, + }, + { + $push: { + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); + + await User.updateOne( + { + _id: testUsers[2]._id, + }, + { + $push: { + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> organizationsMemberConnection", () => { + it(`when no organization exists with _id === args.orgId`, async () => { + const args: QueryOrganizationsMemberConnectionArgs = { + orgId: Types.ObjectId().toString(), + first: 1, + skip: 1, + where: null, + orderBy: null, + }; + + const organizationsMemberConnectionPayload = + await organizationsMemberConnectionResolver?.({}, args, {}); + + expect(organizationsMemberConnectionPayload).toEqual({ + pageInfo: { + hasNextPage: false, + hasPreviousPage: false, + totalPages: 1, + nextPageNo: null, + prevPageNo: null, + currPageNo: 1, + }, + edges: [], + aggregate: { + count: 0, + }, + }); + }); + + // it(`returns paginated list of users filtered by + // args.where === { id: testUsers[1].id, firstName: testUsers[1].firstName, + // lastName: testUsers[1].lastName, email: testUsers[1].email, + // appLanguageCode: testUsers[1].appLanguageCode } and sorted by + // args.orderBy === 'id_ASC'`, async () => { + // const where = { + // _id: testUsers[1].id, + // firstName: testUsers[1].firstName, + // lastName: testUsers[1].lastName, + // email: testUsers[1].email, + // appLanguageCode: testUsers[1].appLanguageCode, + // }; + + // const sort = { + // _id: 1, + // }; + + // const args: QueryOrganizationsMemberConnectionArgs = { + // orgId: testOrganization.id, + // first: 1, + // skip: 1, + // where: { + // id: testUsers[1].id, + // firstName: testUsers[1].firstName, + // lastName: testUsers[1].lastName, + // email: testUsers[1].email, + // appLanguageCode: testUsers[1].appLanguageCode, + // }, + // orderBy: UserOrderByInput.IdAsc, + // }; + + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // // .limit(1) + // // .skip(1) + // .sort(sort) + // .select(['-password']) + // .lean(); + + // expect(organizationsMemberConnectionPayload).toEqual({ + // pageInfo: { + // hasNextPage: false, + // hasPreviousPage: false, + // totalPages: 1, + // nextPageNo: null, + // prevPageNo: null, + // currPageNo: 1, + // }, + // edges: users, + // aggregate: { + // count: 1, + // }, + // }); + + // it(`returns paginated list of users filtered by + // args.where === { id_not: testUsers[2]._id, firstName_not: testUsers[2].firstName, + // lastName_not: testUsers[2].lastName, email_not: testUsers[2].email, + // appLanguageCode_not: testUsers[2].appLanguageCode } and + // sorted by args.orderBy === 'id_Desc'`, async () => { + // const where = { + // _id: { + // $ne: testUsers[2]._id, + // }, + // firstName: { + // $ne: testUsers[2].firstName, + // }, + // lastName: { + // $ne: testUsers[2].lastName, + // }, + // email: { + // $ne: testUsers[2].email, + // }, + // appLanguageCode: { + // $ne: testUsers[2].appLanguageCode, + // }, + // }; + // const sort = { + // _id: -1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // id_not: testUsers[2]._id, + // firstName_not: testUsers[2].firstName, + // lastName_not: testUsers[2].lastName, + // email_not: testUsers[2].email, + // appLanguageCode_not: testUsers[2].appLanguageCode, + // }, + // orderBy: UserOrderByInput.IdDesc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users filtered by + // args.where === { id_in: [testUsers[1].id], firstName_in: [testUsers[1].firstName], + // lastName_in: [testUsers[1].lastName], email_in: [testUsers[1].email], + // appLanguageCode_in: [testUsers[1].appLanguageCode] } and + // sorted by args.orderBy === 'firstName_ASC'`, async () => { + // const where = { + // _id: { + // $in: [testUsers[1].id], + // }, + // firstName: { + // $in: [testUsers[1].firstName], + // }, + // lastName: { + // $in: [testUsers[1].lastName], + // }, + // email: { + // $in: [testUsers[1].email], + // }, + // appLanguageCode: { + // $in: [testUsers[1].appLanguageCode], + // }, + // }; + // const sort = { + // firstName: 1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // id_in: [testUsers[1].id], + // firstName_in: [testUsers[1].firstName], + // lastName_in: [testUsers[1].lastName], + // email_in: [testUsers[1].email], + // appLanguageCode_in: [testUsers[1].appLanguageCode], + // }, + // orderBy: UserOrderByInput.FirstNameAsc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users filtered by + // args.where === { id_not_in: [testUsers[2]._id], firstName_not_in: [testUsers[2].firstName], + // lastName_not_in: [testUsers[2].lastName], email_not_in: [testUsers[2].email], + // appLanguageCode_not_in: [testUsers[2].appLanguageCode] } and + // sorted by args.orderBy === 'FirstNameDesc'`, async () => { + // const where = { + // _id: { + // $nin: [testUsers[2]._id], + // }, + // firstName: { + // $nin: [testUsers[2].firstName], + // }, + // lastName: { + // $nin: [testUsers[2].lastName], + // }, + // email: { + // $nin: [testUsers[2].email], + // }, + // appLanguageCode: { + // $nin: [testUsers[2].appLanguageCode], + // }, + // }; + // const sort = { + // firstName: -1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // id_not_in: [testUsers[2]._id], + // firstName_not_in: [testUsers[2].firstName], + // lastName_not_in: [testUsers[2].lastName], + // email_not_in: [testUsers[2].email], + // appLanguageCode_not_in: [testUsers[2].appLanguageCode], + // }, + // orderBy: UserOrderByInput.FirstNameDesc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users filtered by + // args.where === { firstName_contains: testUsers[1].firstName, + // lastName_contains: testUsers[1].lastName, email_contains: testUsers[1].email, + // appLanguageCode_contains: testUsers[1].appLanguageCode } and + // sorted by args.orderBy === 'lastName_ASC'`, async () => { + // const where = { + // firstName: { + // $regex: testUsers[1].firstName, + // $options: 'i', + // }, + // lastName: { + // $regex: testUsers[1].lastName, + // $options: 'i', + // }, + // email: { + // $regex: testUsers[1].email, + // $options: 'i', + // }, + // appLanguageCode: { + // $regex: testUsers[1].appLanguageCode, + // $options: 'i', + // }, + // }; + // const sort = { + // lastName: 1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // firstName_contains: testUsers[1].firstName, + // lastName_contains: testUsers[1].lastName, + // email_contains: testUsers[1].email, + // appLanguageCode_contains: testUsers[1].appLanguageCode, + // }, + // orderBy: UserOrderByInput.LastNameAsc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users filtered by + // args.where === { firstName_starts_with: testUsers[1].firstName, + // lastName_starts_with: testUsers[1].lastName, email_starts_with: testUsers[1].email, + // appLanguageCode_starts_with: testUsers[1].appLanguageCode } and + // sorted by args.orderBy === 'lastName_DESC'`, async () => { + // const where = { + // firstName: new RegExp('^' + testUsers[1].firstName), + // lastName: new RegExp('^' + testUsers[1].lastName), + // email: new RegExp('^' + testUsers[1].email), + // appLanguageCode: new RegExp('^' + testUsers[1].appLanguageCode), + // }; + // const sort = { + // lastName: -1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // firstName_starts_with: testUsers[1].firstName, + // lastName_starts_with: testUsers[1].lastName, + // email_starts_with: testUsers[1].email, + // appLanguageCode_starts_with: testUsers[1].appLanguageCode, + // }, + // orderBy: UserOrderByInput.LastNameDesc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users sorted by + // args.orderBy === 'appLanguageCode_ASC'`, async () => { + // const where = {}; + // const sort = { + // appLanguageCode: 1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.AppLanguageCodeAsc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users sorted by + // args.orderBy === 'appLanguageCode_DESC'`, async () => { + // const where = {}; + // const sort = { + // appLanguageCode: -1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.AppLanguageCodeDesc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users + // sorted by args.orderBy === 'email_ASC'`, async () => { + // const where = {}; + // const sort = { + // email: 1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.EmailAsc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users + // sorted by args.orderBy === 'email_DESC'`, async () => { + // const where = {}; + // const sort = { + // email: -1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.EmailDesc, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); + // it(`returns paginated list of users sorted by 'email_DESC' if + // args.orderBy === undefined`, async () => { + // const where = {}; + // const sort = { + // email: -1, + // }; + // const args: QueryOrganizationsMemberConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: undefined, + // }; + // const organizationsMemberConnectionPayload = + // await organizationsMemberConnectionResolver?.({}, args, {}); + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + // expect(organizationsMemberConnectionPayload).toEqual(users); + // }); +}); diff --git a/__tests__/resolvers/Query/post.spec.ts b/__tests__/resolvers/Query/post.spec.ts new file mode 100644 index 0000000000..7a401a4ce8 --- /dev/null +++ b/__tests__/resolvers/Query/post.spec.ts @@ -0,0 +1,157 @@ +import "dotenv/config"; +import { post as postResolver } from "../../../src/lib/resolvers/Query/post"; +import { + User, + Organization, + Post, + Comment, + Interface_Post, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { nanoid } from "nanoid"; +import { Document, Types } from "mongoose"; +import { POST_NOT_FOUND } from "../../../src/constants"; +import { QueryPostArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testPost: Interface_Post & Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + testPost = await Post.create({ + text: "text", + creator: testUser._id, + organization: testOrganization._id, + }); + + const testComment = await Comment.create({ + text: "text", + creator: testUser._id, + post: testPost._id, + }); + + await Post.updateOne( + { + _id: testPost._id, + }, + { + $push: { + likedBy: testUser._id, + comments: testComment._id, + }, + $inc: { + likeCount: 1, + commentCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> post", () => { + it("throws NotFoundError if no post exists with _id === args.id", async () => { + try { + const args: QueryPostArgs = { + id: Types.ObjectId().toString(), + }; + + await postResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(POST_NOT_FOUND); + } + }); + + it(`returns post object`, async () => { + const args: QueryPostArgs = { + id: testPost._id, + }; + + const postPayload = await postResolver?.({}, args, {}); + + const post = await Post.findOne({ _id: testPost._id }) + .populate("organization") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("likedBy") + .populate("creator", "-password") + .lean(); + + expect(postPayload).toEqual(post); + }); + + it(`returns post object with post.likeCount === 0 and post.commentCount === 0`, async () => { + await Post.updateOne( + { + _id: testPost._id, + }, + { + $set: { + likedBy: [], + comments: [], + }, + $inc: { + likeCount: -1, + commentCount: -1, + }, + } + ); + + const args: QueryPostArgs = { + id: testPost._id, + }; + + const postPayload = await postResolver?.({}, args, {}); + + const post = await Post.findOne({ _id: testPost._id }) + .populate("organization") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("likedBy") + .populate("creator", "-password") + .lean(); + + expect(postPayload).toEqual(post); + }); +}); diff --git a/__tests__/resolvers/Query/posts.spec.ts b/__tests__/resolvers/Query/posts.spec.ts new file mode 100644 index 0000000000..6aee50a3ff --- /dev/null +++ b/__tests__/resolvers/Query/posts.spec.ts @@ -0,0 +1,740 @@ +import "dotenv/config"; +import { posts as postsResolver } from "../../../src/lib/resolvers/Query/posts"; +import { User, Organization, Post, Comment } from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { nanoid } from "nanoid"; +import { + QueryPostsArgs, + PostOrderByInput, +} from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testPosts = await Post.insertMany([ + { + text: `text${nanoid()}`, + title: `title${nanoid()}`, + imageUrl: `imageUrl${nanoid()}`, + videoUrl: `videoUrl${nanoid()}`, + creator: testUser._id, + organization: testOrganization._id, + }, + { + text: `text${nanoid()}`, + title: `title${nanoid()}`, + imageUrl: `imageUrl${nanoid()}`, + videoUrl: `videoUrl${nanoid()}`, + creator: testUser._id, + organization: testOrganization._id, + }, + ]); + + const testComments = await Comment.insertMany([ + { + text: "text", + creator: testUser._id, + post: testPosts[0]._id, + }, + { + text: "text", + creator: testUser._id, + post: testPosts[1]._id, + }, + ]); + + await Post.updateOne( + { + _id: testPosts[0]._id, + }, + { + $push: { + likedBy: testUser._id, + comments: testComments[0]._id, + }, + $inc: { + likeCount: 1, + commentCount: 1, + }, + } + ); + + await Post.updateOne( + { + _id: testPosts[1]._id, + }, + { + $push: { + likedBy: testUser._id, + comments: testComments[1]._id, + }, + $inc: { + likeCount: 1, + commentCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> posts", () => { + it(`returns list of all existing posts without sorting if args.orderBy === null`, async () => { + const sort = {}; + const args: QueryPostsArgs = { + orderBy: null, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post._id + if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.IdAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post._id + if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.IdDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post.text + if args.orderBy === 'text_ASC'`, async () => { + const sort = { + text: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.TextAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.text + if args.orderBy === 'text_DESC'`, async () => { + const sort = { + text: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.TextDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post.title + if args.orderBy === 'title_ASC'`, async () => { + const sort = { + title: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.TitleAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.title + if args.orderBy === 'title_DESC'`, async () => { + const sort = { + title: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.TitleDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post.createdAt + if args.orderBy === 'createdAt_ASC'`, async () => { + const sort = { + createdAt: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.CreatedAtAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.createdAt + if args.orderBy === 'createdAt_DESC'`, async () => { + const sort = { + createdAt: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.CreatedAtDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post.imageUrl + if args.orderBy === 'imageUrl_ASC'`, async () => { + const sort = { + imageUrl: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.ImageUrlAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.imageUrl + if args.orderBy === 'imageUrl_DESC'`, async () => { + const sort = { + imageUrl: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.ImageUrlDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post.videoUrl + if args.orderBy === 'videoUrl_ASC'`, async () => { + const sort = { + videoUrl: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.VideoUrlAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.videoUrl + if args.orderBy === 'videoUrl_DESC'`, async () => { + const sort = { + videoUrl: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.VideoUrlDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post.likeCount + if args.orderBy === 'likeCount_ASC'`, async () => { + const sort = { + likeCount: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.LikeCountAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.likeCount + if args.orderBy === 'likeCount_DESC'`, async () => { + const sort = { + likeCount: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.LikeCountDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by ascending order of post.commentCount + if args.orderBy === 'commentCount_ASC'`, async () => { + const sort = { + commentCount: 1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.CommentCountAsc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.commentCount + if args.orderBy === 'commentCount_DESC'`, async () => { + const sort = { + commentCount: -1, + }; + + const args: QueryPostsArgs = { + orderBy: PostOrderByInput.CommentCountDesc, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); + + it(`returns list of all existing posts sorted by descending order of post.commentCount + if args.orderBy === undefined`, async () => { + const sort = { + commentCount: -1, + }; + + const args: QueryPostsArgs = { + orderBy: undefined, + }; + + const postsPayload = await postsResolver?.({}, args, {}); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + expect(postsPayload).toEqual(posts); + }); +}); diff --git a/__tests__/resolvers/Query/postsByOrganization.spec.ts b/__tests__/resolvers/Query/postsByOrganization.spec.ts new file mode 100644 index 0000000000..cc07b73eed --- /dev/null +++ b/__tests__/resolvers/Query/postsByOrganization.spec.ts @@ -0,0 +1,751 @@ +import "dotenv/config"; +import { postsByOrganization as postsByOrganizationResolver } from "../../../src/lib/resolvers/Query/postsByOrganization"; +import { + User, + Organization, + Post, + Comment, + Interface_Organization, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { nanoid } from "nanoid"; +import { + QueryPostsByOrganizationArgs, + PostOrderByInput, +} from "../../../src/generated/graphqlCodegen"; +import { Document } from "mongoose"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testPosts = await Post.insertMany([ + { + text: `text${nanoid()}`, + title: `title${nanoid()}`, + imageUrl: `imageUrl${nanoid()}`, + videoUrl: `videoUrl${nanoid()}`, + creator: testUser._id, + organization: testOrganization._id, + }, + { + text: `text${nanoid()}`, + title: `title${nanoid()}`, + imageUrl: `imageUrl${nanoid()}`, + videoUrl: `videoUrl${nanoid()}`, + creator: testUser._id, + organization: testOrganization._id, + }, + ]); + + const testComments = await Comment.insertMany([ + { + text: "text", + creator: testUser._id, + post: testPosts[0]._id, + }, + { + text: "text", + creator: testUser._id, + post: testPosts[1]._id, + }, + ]); + + await Post.updateOne( + { + _id: testPosts[0]._id, + }, + { + $push: { + likedBy: testUser._id, + comments: testComments[0]._id, + }, + $inc: { + likeCount: 1, + commentCount: 1, + }, + } + ); + + await Post.updateOne( + { + _id: testPosts[1]._id, + }, + { + $push: { + likedBy: testUser._id, + comments: testComments[1]._id, + }, + $inc: { + likeCount: 1, + commentCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> posts", () => { + it(`returns list of all existing posts without sorting if args.orderBy === null`, async () => { + const sort = {}; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: null, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post._id if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.IdAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post._id if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.IdDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post.text if args.orderBy === 'text_ASC'`, async () => { + const sort = { + text: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.TextAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.text if args.orderBy === 'text_DESC'`, async () => { + const sort = { + text: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.TextDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post.title if args.orderBy === 'title_ASC'`, async () => { + const sort = { + title: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.TitleAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.title if args.orderBy === 'title_DESC'`, async () => { + const sort = { + title: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.TitleDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post.createdAt if args.orderBy === 'createdAt_ASC'`, async () => { + const sort = { + createdAt: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.CreatedAtAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.createdAt if args.orderBy === 'createdAt_DESC'`, async () => { + const sort = { + createdAt: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.CreatedAtDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post.imageUrl if args.orderBy === 'imageUrl_ASC'`, async () => { + const sort = { + imageUrl: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.ImageUrlAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.imageUrl if args.orderBy === 'imageUrl_DESC'`, async () => { + const sort = { + imageUrl: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.ImageUrlDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post.videoUrl if args.orderBy === 'videoUrl_ASC'`, async () => { + const sort = { + videoUrl: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.VideoUrlAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.videoUrl if args.orderBy === 'videoUrl_DESC'`, async () => { + const sort = { + videoUrl: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.VideoUrlDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post.likeCount if args.orderBy === 'likeCount_ASC'`, async () => { + const sort = { + likeCount: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.LikeCountAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.likeCount if args.orderBy === 'likeCount_DESC'`, async () => { + const sort = { + likeCount: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.LikeCountDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by ascending order of post.commentCount if args.orderBy === 'commentCount_ASC'`, async () => { + const sort = { + commentCount: 1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.CommentCountAsc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.commentCount if args.orderBy === 'commentCount_DESC'`, async () => { + const sort = { + commentCount: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: PostOrderByInput.CommentCountDesc, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); + + it(`returns list of all existing posts having post.organization with _id === args.id + sorted by descending order of post.commentCount if args.orderBy === undefined`, async () => { + const sort = { + commentCount: -1, + }; + + const args: QueryPostsByOrganizationArgs = { + id: testOrganization.id, + orderBy: undefined, + }; + + const postsByOrganizationPayload = await postsByOrganizationResolver?.( + {}, + args, + {} + ); + + const postsByOrganization = await Post.find({ + organization: testOrganization._id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + expect(postsByOrganizationPayload).toEqual(postsByOrganization); + }); +}); diff --git a/__tests__/resolvers/Query/postsByOrganizationConnection.spec.ts b/__tests__/resolvers/Query/postsByOrganizationConnection.spec.ts new file mode 100644 index 0000000000..3fe33b04c6 --- /dev/null +++ b/__tests__/resolvers/Query/postsByOrganizationConnection.spec.ts @@ -0,0 +1,586 @@ +import "dotenv/config"; +import { postsByOrganizationConnection as postsByOrganizationConnectionResolver } from "../../../src/lib/resolvers/Query/postsByOrganizationConnection"; +import { + Comment, + Interface_Organization, + Organization, + Post, + User, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { Document, Types } from "mongoose"; +import { nanoid } from "nanoid"; +import { QueryPostsByOrganizationConnectionArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testOrganization: Interface_Organization & + Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + apiUrl: "apiUrl", + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testPosts = await Post.insertMany([ + { + text: `text${nanoid().toLowerCase()}`, + title: `title${nanoid().toLowerCase()}`, + imageUrl: `imageUrl${nanoid().toLowerCase()}`, + videoUrl: `videoUrl${nanoid().toLowerCase()}`, + creator: testUser._id, + organization: testOrganization._id, + }, + { + text: `text${nanoid().toLowerCase()}`, + title: `title${nanoid().toLowerCase()}`, + imageUrl: `imageUrl${nanoid().toLowerCase()}`, + videoUrl: `videoUrl${nanoid().toLowerCase()}`, + creator: testUser._id, + organization: testOrganization._id, + }, + { + text: `text${nanoid().toLowerCase()}`, + title: `title${nanoid().toLowerCase()}`, + imageUrl: `imageUrl${nanoid().toLowerCase()}`, + videoUrl: `videoUrl${nanoid().toLowerCase()}`, + creator: testUser._id, + organization: testOrganization._id, + }, + ]); + + const testComment = await Comment.create({ + text: "text", + creator: testUser._id, + post: testPosts[0]._id, + }); + + await Post.updateOne( + { + _id: testPosts[0]._id, + }, + { + $push: { + likedBy: testUser._id, + comments: testComment._id, + }, + $inc: { + likeCount: 1, + commentCount: 1, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> users", () => { + it(`when no organization exists with _id === args.id`, async () => { + const args: QueryPostsByOrganizationConnectionArgs = { + id: Types.ObjectId().toString(), + first: 2, + skip: 1, + where: null, + orderBy: null, + }; + + const postsByOrganizationConnectionPayload = + await postsByOrganizationConnectionResolver?.({}, args, {}); + + expect(postsByOrganizationConnectionPayload).toEqual({ + pageInfo: { + hasNextPage: false, + hasPreviousPage: false, + totalPages: 1, + nextPageNo: null, + prevPageNo: null, + currPageNo: 1, + }, + edges: [], + aggregate: { count: 0 }, + }); + }); + + // it(`returns paginated list of users filtered by + // args.where === { id_not: testUsers[2]._id, firstName_not: testUsers[2].firstName, + // lastName_not: testUsers[2].lastName, email_not: testUsers[2].email, + // appLanguageCode_not: testUsers[2].appLanguageCode } and + // sorted by args.orderBy === 'id_Desc'`, async () => { + // const where = { + // _id: { + // $ne: testUsers[2]._id, + // }, + // firstName: { + // $ne: testUsers[2].firstName, + // }, + // lastName: { + // $ne: testUsers[2].lastName, + // }, + // email: { + // $ne: testUsers[2].email, + // }, + // appLanguageCode: { + // $ne: testUsers[2].appLanguageCode, + // }, + // }; + + // const sort = { + // _id: -1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // id_not: testUsers[2]._id, + // firstName_not: testUsers[2].firstName, + // lastName_not: testUsers[2].lastName, + // email_not: testUsers[2].email, + // appLanguageCode_not: testUsers[2].appLanguageCode, + // }, + // orderBy: UserOrderByInput.IdDesc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users filtered by + // args.where === { id_in: [testUsers[1].id], firstName_in: [testUsers[1].firstName], + // lastName_in: [testUsers[1].lastName], email_in: [testUsers[1].email], + // appLanguageCode_in: [testUsers[1].appLanguageCode] } and + // sorted by args.orderBy === 'firstName_ASC'`, async () => { + // const where = { + // _id: { + // $in: [testUsers[1].id], + // }, + // firstName: { + // $in: [testUsers[1].firstName], + // }, + // lastName: { + // $in: [testUsers[1].lastName], + // }, + // email: { + // $in: [testUsers[1].email], + // }, + // appLanguageCode: { + // $in: [testUsers[1].appLanguageCode], + // }, + // }; + + // const sort = { + // firstName: 1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // id_in: [testUsers[1].id], + // firstName_in: [testUsers[1].firstName], + // lastName_in: [testUsers[1].lastName], + // email_in: [testUsers[1].email], + // appLanguageCode_in: [testUsers[1].appLanguageCode], + // }, + // orderBy: UserOrderByInput.FirstNameAsc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users filtered by + // args.where === { id_not_in: [testUsers[2]._id], firstName_not_in: [testUsers[2].firstName], + // lastName_not_in: [testUsers[2].lastName], email_not_in: [testUsers[2].email], + // appLanguageCode_not_in: [testUsers[2].appLanguageCode] } and + // sorted by args.orderBy === 'FirstNameDesc'`, async () => { + // const where = { + // _id: { + // $nin: [testUsers[2]._id], + // }, + // firstName: { + // $nin: [testUsers[2].firstName], + // }, + // lastName: { + // $nin: [testUsers[2].lastName], + // }, + // email: { + // $nin: [testUsers[2].email], + // }, + // appLanguageCode: { + // $nin: [testUsers[2].appLanguageCode], + // }, + // }; + + // const sort = { + // firstName: -1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // id_not_in: [testUsers[2]._id], + // firstName_not_in: [testUsers[2].firstName], + // lastName_not_in: [testUsers[2].lastName], + // email_not_in: [testUsers[2].email], + // appLanguageCode_not_in: [testUsers[2].appLanguageCode], + // }, + // orderBy: UserOrderByInput.FirstNameDesc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users filtered by + // args.where === { firstName_contains: testUsers[1].firstName, + // lastName_contains: testUsers[1].lastName, email_contains: testUsers[1].email, + // appLanguageCode_contains: testUsers[1].appLanguageCode } and + // sorted by args.orderBy === 'lastName_ASC'`, async () => { + // const where = { + // firstName: { + // $regex: testUsers[1].firstName, + // $options: 'i', + // }, + // lastName: { + // $regex: testUsers[1].lastName, + // $options: 'i', + // }, + // email: { + // $regex: testUsers[1].email, + // $options: 'i', + // }, + // appLanguageCode: { + // $regex: testUsers[1].appLanguageCode, + // $options: 'i', + // }, + // }; + + // const sort = { + // lastName: 1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // firstName_contains: testUsers[1].firstName, + // lastName_contains: testUsers[1].lastName, + // email_contains: testUsers[1].email, + // appLanguageCode_contains: testUsers[1].appLanguageCode, + // }, + // orderBy: UserOrderByInput.LastNameAsc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users filtered by + // args.where === { firstName_starts_with: testUsers[1].firstName, + // lastName_starts_with: testUsers[1].lastName, email_starts_with: testUsers[1].email, + // appLanguageCode_starts_with: testUsers[1].appLanguageCode } and + // sorted by args.orderBy === 'lastName_DESC'`, async () => { + // const where = { + // firstName: new RegExp('^' + testUsers[1].firstName), + // lastName: new RegExp('^' + testUsers[1].lastName), + // email: new RegExp('^' + testUsers[1].email), + // appLanguageCode: new RegExp('^' + testUsers[1].appLanguageCode), + // }; + + // const sort = { + // lastName: -1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: { + // firstName_starts_with: testUsers[1].firstName, + // lastName_starts_with: testUsers[1].lastName, + // email_starts_with: testUsers[1].email, + // appLanguageCode_starts_with: testUsers[1].appLanguageCode, + // }, + // orderBy: UserOrderByInput.LastNameDesc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users sorted by + // args.orderBy === 'appLanguageCode_ASC'`, async () => { + // const where = {}; + + // const sort = { + // appLanguageCode: 1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.AppLanguageCodeAsc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users sorted by + // args.orderBy === 'appLanguageCode_DESC'`, async () => { + // const where = {}; + + // const sort = { + // appLanguageCode: -1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.AppLanguageCodeDesc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users + // sorted by args.orderBy === 'email_ASC'`, async () => { + // const where = {}; + + // const sort = { + // email: 1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.EmailAsc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users + // sorted by args.orderBy === 'email_DESC'`, async () => { + // const where = {}; + + // const sort = { + // email: -1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: UserOrderByInput.EmailDesc, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); + + // it(`returns paginated list of users sorted by 'email_DESC' if + // args.orderBy === undefined`, async () => { + // const where = {}; + + // const sort = { + // email: -1, + // }; + + // const args: QueryPostsByOrganizationConnectionArgs = { + // first: 2, + // skip: 1, + // where: null, + // orderBy: undefined, + // }; + + // const postsByOrganizationConnectionPayload = + // await postsByOrganizationConnectionResolver?.({}, args, {}); + + // const users = await User.find(where) + // .limit(2) + // .skip(1) + // .sort(sort) + // .select(['-password']) + // .populate('createdOrganizations') + // .populate('createdEvents') + // .populate('joinedOrganizations') + // .populate('registeredEvents') + // .populate('eventAdmin') + // .populate('adminFor') + // .lean(); + + // expect(postsByOrganizationConnectionPayload).toEqual(users); + // }); +}); diff --git a/__tests__/resolvers/Query/registeredEventsByUser.spec.ts b/__tests__/resolvers/Query/registeredEventsByUser.spec.ts new file mode 100644 index 0000000000..053454305a --- /dev/null +++ b/__tests__/resolvers/Query/registeredEventsByUser.spec.ts @@ -0,0 +1,854 @@ +import "dotenv/config"; +import { registeredEventsByUser as registeredEventsByUserResolver } from "../../../src/lib/resolvers/Query/registeredEventsByUser"; +import { + Event, + User, + Organization, + Interface_User, + Task, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { nanoid } from "nanoid"; +import { + EventOrderByInput, + QueryRegisteredEventsByUserArgs, +} from "../../../src/generated/graphqlCodegen"; +import { Document } from "mongoose"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + }, + } + ); + + const testEvents = await Event.insertMany([ + { + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: `title${nanoid()}`, + description: `description${nanoid()}`, + allDay: true, + startDate: new Date().toString(), + endDate: new Date().toString(), + startTime: new Date().toString(), + endTime: new Date().toString(), + recurrance: "ONCE", + location: `location${nanoid()}`, + }, + { + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: `title${nanoid()}`, + description: `description${nanoid()}`, + allDay: true, + startDate: new Date().toString(), + endDate: new Date().toString(), + startTime: new Date().toString(), + endTime: new Date().toString(), + recurrance: "ONCE", + location: `location${nanoid()}`, + }, + ]); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $set: { + createdEvents: [testEvents[0]._id, testEvents[1]._id], + registeredEvents: [testEvents[0]._id], + eventAdmin: [testEvents[0]._id, testEvents[1]._id], + }, + } + ); + + const testTasks = await Task.insertMany([ + { + title: "title", + event: testEvents[0]._id, + creator: testUser._id, + }, + { + title: "title", + event: testEvents[1]._id, + creator: testUser._id, + }, + ]); + + await Event.updateOne( + { + _id: testEvents[0]._id, + }, + { + $set: { + tasks: [testTasks[0]._id], + }, + } + ); + + await Event.updateOne( + { + _id: testEvents[1]._id, + }, + { + $set: { + tasks: [testTasks[1]._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> events", () => { + it(`returns list of all existing events sorted by ascending order of event._id + if args.orderBy === 'id_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.IdAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event._id + if args.orderBy === 'id_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.IdDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.title + if args.orderBy === 'title_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + title: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.TitleAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.title + if args.orderBy === 'title_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + title: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.TitleDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.description + if args.orderBy === 'description_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + description: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.DescriptionAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.description + if args.orderBy === 'description_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + description: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.DescriptionDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.startDate + if args.orderBy === 'startDate_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + startDate: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.StartDateAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.startDate + if args.orderBy === 'startDate_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + startDate: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.StartDateDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.endDate + if args.orderBy === 'endDate_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + endDate: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.EndDateAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.endDate + if args.orderBy === 'endDate_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + endDate: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.EndDateDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.allDay + if args.orderBy === 'allDay_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + allDay: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.AllDayAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.allDay + if args.orderBy === 'allDay_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + allDay: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.AllDayDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.startTime + if args.orderBy === 'startTime_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + startTime: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.StartTimeAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.startTime + if args.orderBy === 'startTime_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + startTime: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.StartTimeDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.endTime + if args.orderBy === 'endTime_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + endTime: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.EndTimeAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.endTime + if args.orderBy === 'endTime_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + endTime: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.EndTimeDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.recurrance + if args.orderBy === 'recurrance_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + recurrance: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.RecurranceAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.recurrance + if args.orderBy === 'recurrance_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + recurrance: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.RecurranceDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by ascending order of event.location + if args.orderBy === 'location_ASC where user with _id === args.id is a registrant'`, async () => { + const sort = { + location: 1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.LocationAsc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.location + if args.orderBy === 'location_DESC where user with _id === args.id is a registrant'`, async () => { + const sort = { + location: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: EventOrderByInput.LocationDesc, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events sorted by descending order of event.location + if args.orderBy === undefined`, async () => { + const sort = { + location: -1, + }; + + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: undefined, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); + + it(`returns list of all existing events without sorting if args.orderBy === null`, async () => { + const sort = {}; + const args: QueryRegisteredEventsByUserArgs = { + id: testUser._id, + orderBy: null, + }; + + const registeredEventsByUser = await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: testUser._id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + const registeredEventsByUserPayload = + await registeredEventsByUserResolver?.({}, args, {}); + + expect(registeredEventsByUserPayload).toEqual(registeredEventsByUser); + }); +}); diff --git a/__tests__/resolvers/Query/registrantsByEvent.spec.ts b/__tests__/resolvers/Query/registrantsByEvent.spec.ts new file mode 100644 index 0000000000..7facbbbab8 --- /dev/null +++ b/__tests__/resolvers/Query/registrantsByEvent.spec.ts @@ -0,0 +1,111 @@ +import "dotenv/config"; +import { registrantsByEvent as registrantsByEventResolver } from "../../../src/lib/resolvers/Query/registrantsByEvent"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Event, + Interface_Event, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Document, Types } from "mongoose"; +import { QueryRegistrantsByEventArgs } from "../../../src/generated/graphqlCodegen"; +import { EVENT_NOT_FOUND } from "../../../src/constants"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + testEvent = await Event.create({ + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + createdEvents: testEvent._id, + registeredEvents: testEvent._id, + eventAdmin: testEvent._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> registrantsByEvent", () => { + it("throws NotFoundError if no event exists with _id === args.id", async () => { + try { + const args: QueryRegistrantsByEventArgs = { + id: Types.ObjectId().toString(), + }; + + await registrantsByEventResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(EVENT_NOT_FOUND); + } + }); + + it("returns list of all registrants for event with _id === args.id", async () => { + const args: QueryRegistrantsByEventArgs = { id: testEvent._id }; + + const registrantsByEventPayload = await registrantsByEventResolver?.( + {}, + args, + {} + ); + + const event = await Event.findOne({ + _id: testEvent._id, + }) + .populate("registrants.user", "-password") + .lean(); + + const registrantsByEvent = event?.registrants.map((registrant) => { + return registrant.user; + }); + + expect(registrantsByEventPayload).toEqual(registrantsByEvent); + }); +}); diff --git a/__tests__/resolvers/Query/tasksByEvent.spec.ts b/__tests__/resolvers/Query/tasksByEvent.spec.ts new file mode 100644 index 0000000000..1535eaff72 --- /dev/null +++ b/__tests__/resolvers/Query/tasksByEvent.spec.ts @@ -0,0 +1,390 @@ +import "dotenv/config"; +import { tasksByEvent as tasksByEventResolver } from "../../../src/lib/resolvers/Query/tasksByEvent"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Event, + Task, + Interface_Event, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Document } from "mongoose"; +import { + QueryTasksByEventArgs, + TaskOrderByInput, +} from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testEvent: Interface_Event & Document; + +beforeAll(async () => { + await connect(); + + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + testEvent = await Event.create({ + creator: testUser._id, + registrants: [ + { + userId: testUser._id, + user: testUser._id, + }, + ], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + createdEvents: testEvent._id, + registeredEvents: testEvent._id, + eventAdmin: testEvent._id, + }, + } + ); + + const testTasks = await Task.insertMany([ + { + title: `title${nanoid()}`, + description: `description${nanoid()}`, + event: testEvent._id, + creator: testUser._id, + deadline: new Date(), + }, + { + title: `title${nanoid()}`, + description: `description${nanoid()}`, + event: testEvent._id, + creator: testUser._id, + deadline: new Date(), + }, + ]); + + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $set: { + tasks: [testTasks[0]._id, testTasks[1]._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> tasksByEvent", () => { + it("returns list of all tasks with task.creator === args.id", async () => { + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: null, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task._id if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.IdAsc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task._id if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.IdDesc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.title if args.orderBy === 'title_ASC'`, async () => { + const sort = { + title: 1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.TitleAsc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.title if args.orderBy === 'title_DESC'`, async () => { + const sort = { + title: -1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.TitleDesc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.description if args.orderBy === 'description_ASC'`, async () => { + const sort = { + description: 1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.DescriptionAsc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.description if args.orderBy === 'description_DESC'`, async () => { + const sort = { + description: -1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.DescriptionDesc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.createdAt if args.orderBy === 'createdAt_ASC'`, async () => { + const sort = { + createdAt: 1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.CreatedAtAsc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.createdAt if args.orderBy === 'createdAt_DESC'`, async () => { + const sort = { + createdAt: -1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.CreatedAtDesc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.deadline if args.orderBy === 'deadline_ASC'`, async () => { + const sort = { + deadline: 1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.DeadlineAsc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.deadline if args.orderBy === 'deadline_DESC'`, async () => { + const sort = { + deadline: -1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: TaskOrderByInput.DeadlineDesc, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.deadline if args.orderBy === undefined`, async () => { + const sort = { + deadline: -1, + }; + + const args: QueryTasksByEventArgs = { + id: testEvent.id, + orderBy: undefined, + }; + + const tasksByEventPayload = await tasksByEventResolver?.({}, args, {}); + + const tasksByEvent = await Task.find({ + event: testEvent._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByEventPayload).toEqual(tasksByEvent); + }); +}); diff --git a/__tests__/resolvers/Query/tasksByUser.spec.ts b/__tests__/resolvers/Query/tasksByUser.spec.ts new file mode 100644 index 0000000000..222c4871f2 --- /dev/null +++ b/__tests__/resolvers/Query/tasksByUser.spec.ts @@ -0,0 +1,386 @@ +import "dotenv/config"; +import { tasksByUser as tasksByUserResolver } from "../../../src/lib/resolvers/Query/tasksByUser"; +import { connect, disconnect } from "../../../src/db"; +import { + User, + Organization, + Event, + Task, + Interface_User, +} from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Document } from "mongoose"; +import { + QueryTasksByUserArgs, + TaskOrderByInput, +} from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + const testEvent = await Event.create({ + creator: testUser._id, + registrants: [{ userId: testUser._id, user: testUser._id }], + admins: [testUser._id], + organization: testOrganization._id, + isRegisterable: true, + isPublic: true, + title: "title", + description: "description", + allDay: true, + startDate: new Date().toString(), + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + createdEvents: testEvent._id, + registeredEvents: testEvent._id, + eventAdmin: testEvent._id, + }, + } + ); + + const testTasks = await Task.insertMany([ + { + title: `title${nanoid()}`, + description: `description${nanoid()}`, + event: testEvent._id, + creator: testUser._id, + deadline: new Date(), + }, + { + title: `title${nanoid()}`, + description: `description${nanoid()}`, + event: testEvent._id, + creator: testUser._id, + deadline: new Date(), + }, + ]); + + await Event.updateOne( + { + _id: testEvent._id, + }, + { + $set: { + tasks: [testTasks[0]._id, testTasks[1]._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> tasksByUser", () => { + it(`returns list of all tasks with task.creator === args.id without sorting + if args.orderBy === null`, async () => { + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: null, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task._id if args.orderBy === 'id_ASC'`, async () => { + const sort = { + _id: 1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.IdAsc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task._id if args.orderBy === 'id_DESC'`, async () => { + const sort = { + _id: -1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.IdDesc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.title if args.orderBy === 'title_ASC'`, async () => { + const sort = { + title: 1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.TitleAsc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.title if args.orderBy === 'title_DESC'`, async () => { + const sort = { + title: -1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.TitleDesc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.description if args.orderBy === 'description_ASC'`, async () => { + const sort = { + description: 1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.DescriptionAsc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.description if args.orderBy === 'description_DESC'`, async () => { + const sort = { + description: -1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.DescriptionDesc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.createdAt if args.orderBy === 'createdAt_ASC'`, async () => { + const sort = { + createdAt: 1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.CreatedAtAsc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.createdAt if args.orderBy === 'createdAt_DESC'`, async () => { + const sort = { + createdAt: -1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.CreatedAtDesc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + ascending order of task.deadline if args.orderBy === 'deadline_ASC'`, async () => { + const sort = { + deadline: 1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.DeadlineAsc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.deadline if args.orderBy === 'deadline_DESC'`, async () => { + const sort = { + deadline: -1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: TaskOrderByInput.DeadlineDesc, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); + + it(`returns list of all tasks with task.creator === args.id and sorted by + descending order of task.deadline if args.orderBy === undefined`, async () => { + const sort = { + deadline: -1, + }; + + const args: QueryTasksByUserArgs = { + id: testUser._id, + orderBy: undefined, + }; + + const tasksByUserPayload = await tasksByUserResolver?.({}, args, {}); + + const tasksByUser = await Task.find({ + creator: testUser._id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); + + expect(tasksByUserPayload).toEqual(tasksByUser); + }); +}); diff --git a/__tests__/resolvers/Query/user.spec.ts b/__tests__/resolvers/Query/user.spec.ts new file mode 100644 index 0000000000..720b69a378 --- /dev/null +++ b/__tests__/resolvers/Query/user.spec.ts @@ -0,0 +1,86 @@ +import "dotenv/config"; +import { user as userResolver } from "../../../src/lib/resolvers/Query/user"; +import { connect, disconnect } from "../../../src/db"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { Interface_User, Organization, User } from "../../../src/lib/models"; +import { nanoid } from "nanoid"; +import { Document, Types } from "mongoose"; +import { QueryUserArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUser: Interface_User & Document; + +beforeAll(async () => { + await connect(); + + testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUser._id, + admins: [testUser._id], + members: [testUser._id], + }); + + await User.updateOne( + { + _id: testUser._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> user", () => { + it("throws NotFoundError if no user exists with _id === args.id", async () => { + try { + const args: QueryUserArgs = { + id: Types.ObjectId().toString(), + }; + + await userResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`returns user object`, async () => { + const args: QueryUserArgs = { + id: testUser.id, + }; + + const context = { + userId: testUser.id, + }; + + const userPayload = await userResolver?.({}, args, context); + + const user = await User.findOne({ + _id: testUser._id, + }) + .populate("adminFor") + .lean(); + + expect(userPayload).toEqual({ + ...user, + organizationsBlockedBy: [], + }); + }); +}); diff --git a/__tests__/resolvers/Query/userLanguage.spec.ts b/__tests__/resolvers/Query/userLanguage.spec.ts new file mode 100644 index 0000000000..8b3c8de4fb --- /dev/null +++ b/__tests__/resolvers/Query/userLanguage.spec.ts @@ -0,0 +1,49 @@ +import "dotenv/config"; +import { Types } from "mongoose"; +import { nanoid } from "nanoid"; +import { connect, disconnect } from "../../../src/db"; +import { userLanguage as userLanguageResolver } from "../../../src/lib/resolvers/Query/userLanguage"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { User } from "../../../src/lib/models"; +import { QueryUserLanguageArgs } from "../../../src/generated/graphqlCodegen"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +beforeAll(async () => { + await connect(); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> userLanguage", () => { + it("throws NotFoundError if no user exists with _id === args.userId", async () => { + try { + const args: QueryUserLanguageArgs = { + userId: Types.ObjectId().toString(), + }; + + await userLanguageResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + it(`returns user's appLanguageCode`, async () => { + const testUser = await User.create({ + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: "firstName", + lastName: "lastName", + appLanguageCode: "en", + }); + + const args: QueryUserLanguageArgs = { + userId: testUser?._id, + }; + + const userLanguagePayload = await userLanguageResolver?.({}, args, {}); + + expect(userLanguagePayload).toEqual(testUser.appLanguageCode); + }); +}); diff --git a/__tests__/resolvers/Query/users.spec.ts b/__tests__/resolvers/Query/users.spec.ts new file mode 100644 index 0000000000..13023bfb29 --- /dev/null +++ b/__tests__/resolvers/Query/users.spec.ts @@ -0,0 +1,617 @@ +import "dotenv/config"; +import { users as usersResolver } from "../../../src/lib/resolvers/Query/users"; +import { + Event, + Interface_User, + Organization, + User, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { + UserOrderByInput, + QueryUsersArgs, +} from "../../../src/generated/graphqlCodegen"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { USER_NOT_FOUND } from "../../../src/constants"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; + +beforeAll(async () => { + await connect(); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> users", () => { + it("throws NotFoundError if no user exists", async () => { + try { + const args: QueryUsersArgs = { + orderBy: null, + where: null, + }; + + await usersResolver?.({}, args, {}); + } catch (error: any) { + expect(error.message).toEqual(USER_NOT_FOUND); + } + }); + + describe("", () => { + beforeAll(async () => { + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid()}`, + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid()}`, + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid()}`, + }, + ]); + + const testOrganization = await Organization.create({ + name: "name1", + description: "description1", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id], + apiUrl: "apiUrl1", + }); + + const testEvent = await Event.create({ + title: "title", + description: "description", + recurring: true, + allDay: true, + startDate: new Date().toString(), + isPublic: true, + isRegisterable: true, + creator: testUsers[0]._id, + registrants: [ + { + userId: testUsers[0]._id, + user: testUsers[0]._id, + }, + ], + admins: [testUsers[0]._id], + organization: testOrganization._id, + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $push: { + createdOrganizations: testOrganization._id, + adminFor: testOrganization._id, + joinedOrganizations: testOrganization._id, + createdEvents: testEvent._id, + registeredEvents: testEvent._id, + eventAdmin: testEvent._id, + }, + } + ); + }); + + it(`returns list of all existing users filtered by + args.where === { id: testUsers[1].id, firstName: testUsers[1].firstName, + lastName: testUsers[1].lastName, email: testUsers[1].email, + appLanguageCode: testUsers[1].appLanguageCode } and sorted by + args.orderBy === 'id_ASC'`, async () => { + const where = { + _id: testUsers[1].id, + firstName: testUsers[1].firstName, + lastName: testUsers[1].lastName, + email: testUsers[1].email, + appLanguageCode: testUsers[1].appLanguageCode, + }; + + const sort = { + _id: 1, + }; + + const args: QueryUsersArgs = { + where: { + id: testUsers[1].id, + firstName: testUsers[1].firstName, + lastName: testUsers[1].lastName, + email: testUsers[1].email, + appLanguageCode: testUsers[1].appLanguageCode, + }, + orderBy: UserOrderByInput.IdAsc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users filtered by + args.where === { id_not: testUsers[2]._id, firstName_not: testUsers[2].firstName, + lastName_not: testUsers[2].lastName, email_not: testUsers[2].email, + appLanguageCode_not: testUsers[2].appLanguageCode } and + sorted by args.orderBy === 'id_Desc'`, async () => { + const where = { + _id: { + $ne: testUsers[2]._id, + }, + firstName: { + $ne: testUsers[2].firstName, + }, + lastName: { + $ne: testUsers[2].lastName, + }, + email: { + $ne: testUsers[2].email, + }, + appLanguageCode: { + $ne: testUsers[2].appLanguageCode, + }, + }; + + const sort = { + _id: -1, + }; + + const args: QueryUsersArgs = { + where: { + id_not: testUsers[2]._id, + firstName_not: testUsers[2].firstName, + lastName_not: testUsers[2].lastName, + email_not: testUsers[2].email, + appLanguageCode_not: testUsers[2].appLanguageCode, + }, + orderBy: UserOrderByInput.IdDesc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users filtered by + args.where === { id_in: [testUsers[1].id], firstName_in: [testUsers[1].firstName], + lastName_in: [testUsers[1].lastName], email_in: [testUsers[1].email], + appLanguageCode_in: [testUsers[1].appLanguageCode] } and + sorted by args.orderBy === 'firstName_ASC'`, async () => { + const where = { + _id: { + $in: [testUsers[1].id], + }, + firstName: { + $in: [testUsers[1].firstName], + }, + lastName: { + $in: [testUsers[1].lastName], + }, + email: { + $in: [testUsers[1].email], + }, + appLanguageCode: { + $in: [testUsers[1].appLanguageCode], + }, + }; + + const sort = { + firstName: 1, + }; + + const args: QueryUsersArgs = { + where: { + id_in: [testUsers[1].id], + firstName_in: [testUsers[1].firstName], + lastName_in: [testUsers[1].lastName], + email_in: [testUsers[1].email], + appLanguageCode_in: [testUsers[1].appLanguageCode], + }, + orderBy: UserOrderByInput.FirstNameAsc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users filtered by + args.where === { id_not_in: [testUsers[2]._id], firstName_not_in: [testUsers[2].firstName], + lastName_not_in: [testUsers[2].lastName], email_not_in: [testUsers[2].email], + appLanguageCode_not_in: [testUsers[2].appLanguageCode] } and + sorted by args.orderBy === 'FirstNameDesc'`, async () => { + const where = { + _id: { + $nin: [testUsers[2]._id], + }, + firstName: { + $nin: [testUsers[2].firstName], + }, + lastName: { + $nin: [testUsers[2].lastName], + }, + email: { + $nin: [testUsers[2].email], + }, + appLanguageCode: { + $nin: [testUsers[2].appLanguageCode], + }, + }; + + const sort = { + firstName: -1, + }; + + const args: QueryUsersArgs = { + where: { + id_not_in: [testUsers[2]._id], + firstName_not_in: [testUsers[2].firstName], + lastName_not_in: [testUsers[2].lastName], + email_not_in: [testUsers[2].email], + appLanguageCode_not_in: [testUsers[2].appLanguageCode], + }, + orderBy: UserOrderByInput.FirstNameDesc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users filtered by + args.where === { firstName_contains: testUsers[1].firstName, + lastName_contains: testUsers[1].lastName, email_contains: testUsers[1].email, + appLanguageCode_contains: testUsers[1].appLanguageCode } and + sorted by args.orderBy === 'lastName_ASC'`, async () => { + const where = { + firstName: { + $regex: testUsers[1].firstName, + $options: "i", + }, + lastName: { + $regex: testUsers[1].lastName, + $options: "i", + }, + email: { + $regex: testUsers[1].email, + $options: "i", + }, + appLanguageCode: { + $regex: testUsers[1].appLanguageCode, + $options: "i", + }, + }; + + const sort = { + lastName: 1, + }; + + const args: QueryUsersArgs = { + where: { + firstName_contains: testUsers[1].firstName, + lastName_contains: testUsers[1].lastName, + email_contains: testUsers[1].email, + appLanguageCode_contains: testUsers[1].appLanguageCode, + }, + orderBy: UserOrderByInput.LastNameAsc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users filtered by + args.where === { firstName_starts_with: testUsers[1].firstName, + lastName_starts_with: testUsers[1].lastName, email_starts_with: testUsers[1].email, + appLanguageCode_starts_with: testUsers[1].appLanguageCode } and + sorted by args.orderBy === 'lastName_DESC'`, async () => { + const where = { + firstName: new RegExp("^" + testUsers[1].firstName), + lastName: new RegExp("^" + testUsers[1].lastName), + email: new RegExp("^" + testUsers[1].email), + appLanguageCode: new RegExp("^" + testUsers[1].appLanguageCode), + }; + + const sort = { + lastName: -1, + }; + + const args: QueryUsersArgs = { + where: { + firstName_starts_with: testUsers[1].firstName, + lastName_starts_with: testUsers[1].lastName, + email_starts_with: testUsers[1].email, + appLanguageCode_starts_with: testUsers[1].appLanguageCode, + }, + orderBy: UserOrderByInput.LastNameDesc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users sorted by + args.orderBy === 'appLanguageCode_ASC'`, async () => { + const where = {}; + + const sort = { + appLanguageCode: 1, + }; + + const args: QueryUsersArgs = { + where: null, + orderBy: UserOrderByInput.AppLanguageCodeAsc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users sorted by + args.orderBy === 'appLanguageCode_DESC'`, async () => { + const where = {}; + + const sort = { + appLanguageCode: -1, + }; + + const args: QueryUsersArgs = { + where: null, + orderBy: UserOrderByInput.AppLanguageCodeDesc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users + sorted by args.orderBy === 'email_ASC'`, async () => { + const where = {}; + + const sort = { + email: 1, + }; + + const args: QueryUsersArgs = { + where: null, + orderBy: UserOrderByInput.EmailAsc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users + sorted by args.orderBy === 'email_DESC'`, async () => { + const where = {}; + + const sort = { + email: -1, + }; + + const args: QueryUsersArgs = { + where: null, + orderBy: UserOrderByInput.EmailDesc, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + + it(`returns list of all existing users sorted by 'email_DESC' if + args.orderBy === undefined`, async () => { + const where = {}; + + const sort = { + email: -1, + }; + + const args: QueryUsersArgs = { + where: null, + orderBy: undefined, + }; + + const usersPayload = await usersResolver?.({}, args, {}); + + let users = await User.find(where) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + users = users.map((user) => ({ + ...user, + organizationsBlockedBy: [], + })); + + expect(usersPayload).toEqual(users); + }); + }); +}); diff --git a/__tests__/resolvers/Query/usersConnection.spec.ts b/__tests__/resolvers/Query/usersConnection.spec.ts new file mode 100644 index 0000000000..702c12a665 --- /dev/null +++ b/__tests__/resolvers/Query/usersConnection.spec.ts @@ -0,0 +1,666 @@ +import "dotenv/config"; +import { usersConnection as usersConnectionResolver } from "../../../src/lib/resolvers/Query/usersConnection"; +import { + Event, + Interface_User, + Organization, + User, +} from "../../../src/lib/models"; +import { connect, disconnect } from "../../../src/db"; +import { + UserOrderByInput, + QueryUsersConnectionArgs, +} from "../../../src/generated/graphqlCodegen"; +import { Document } from "mongoose"; +import { nanoid } from "nanoid"; +import { beforeAll, afterAll, describe, it, expect } from "vitest"; + +let testUsers: (Interface_User & Document)[]; + +beforeAll(async () => { + await connect(); + + testUsers = await User.insertMany([ + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid()}`, + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid()}`, + }, + { + email: `email${nanoid().toLowerCase()}@gmail.com`, + password: "password", + firstName: `firstName${nanoid()}`, + lastName: `lastName${nanoid()}`, + appLanguageCode: `en${nanoid()}`, + }, + ]); + + const testOrganization = await Organization.create({ + name: "name", + description: "description", + isPublic: true, + creator: testUsers[0]._id, + admins: [testUsers[0]._id], + members: [testUsers[0]._id], + apiUrl: "apiUrl", + }); + + const testEvent = await Event.create({ + title: "title", + description: "description", + recurring: true, + allDay: true, + startDate: new Date().toString(), + isPublic: true, + isRegisterable: true, + creator: testUsers[0]._id, + registrants: [ + { + userId: testUsers[0]._id, + user: testUsers[0]._id, + }, + ], + admins: [testUsers[0]._id], + organization: testOrganization._id, + }); + + await User.updateOne( + { + _id: testUsers[0]._id, + }, + { + $set: { + createdOrganizations: [testOrganization._id], + adminFor: [testOrganization._id], + joinedOrganizations: [testOrganization._id], + createdEvents: [testEvent._id], + registeredEvents: [testEvent._id], + eventAdmin: [testEvent._id], + }, + } + ); +}); + +afterAll(async () => { + await disconnect(); +}); + +describe("resolvers -> Query -> usersConnection", () => { + it(`returns paginated list of users filtered by + args.where === { id: testUsers[1].id, firstName: testUsers[1].firstName, + lastName: testUsers[1].lastName, email: testUsers[1].email, + appLanguageCode: testUsers[1].appLanguageCode } and sorted by + args.orderBy === 'id_ASC'`, async () => { + const where = { + _id: testUsers[1].id, + firstName: testUsers[1].firstName, + lastName: testUsers[1].lastName, + email: testUsers[1].email, + appLanguageCode: testUsers[1].appLanguageCode, + }; + + const sort = { + _id: 1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: { + id: testUsers[1].id, + firstName: testUsers[1].firstName, + lastName: testUsers[1].lastName, + email: testUsers[1].email, + appLanguageCode: testUsers[1].appLanguageCode, + }, + orderBy: UserOrderByInput.IdAsc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users filtered by + args.where === { id_not: testUsers[2]._id, firstName_not: testUsers[2].firstName, + lastName_not: testUsers[2].lastName, email_not: testUsers[2].email, + appLanguageCode_not: testUsers[2].appLanguageCode } and + sorted by args.orderBy === 'id_Desc'`, async () => { + const where = { + _id: { + $ne: testUsers[2]._id, + }, + firstName: { + $ne: testUsers[2].firstName, + }, + lastName: { + $ne: testUsers[2].lastName, + }, + email: { + $ne: testUsers[2].email, + }, + appLanguageCode: { + $ne: testUsers[2].appLanguageCode, + }, + }; + + const sort = { + _id: -1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: { + id_not: testUsers[2]._id, + firstName_not: testUsers[2].firstName, + lastName_not: testUsers[2].lastName, + email_not: testUsers[2].email, + appLanguageCode_not: testUsers[2].appLanguageCode, + }, + orderBy: UserOrderByInput.IdDesc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users filtered by + args.where === { id_in: [testUsers[1].id], firstName_in: [testUsers[1].firstName], + lastName_in: [testUsers[1].lastName], email_in: [testUsers[1].email], + appLanguageCode_in: [testUsers[1].appLanguageCode] } and + sorted by args.orderBy === 'firstName_ASC'`, async () => { + const where = { + _id: { + $in: [testUsers[1].id], + }, + firstName: { + $in: [testUsers[1].firstName], + }, + lastName: { + $in: [testUsers[1].lastName], + }, + email: { + $in: [testUsers[1].email], + }, + appLanguageCode: { + $in: [testUsers[1].appLanguageCode], + }, + }; + + const sort = { + firstName: 1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: { + id_in: [testUsers[1].id], + firstName_in: [testUsers[1].firstName], + lastName_in: [testUsers[1].lastName], + email_in: [testUsers[1].email], + appLanguageCode_in: [testUsers[1].appLanguageCode], + }, + orderBy: UserOrderByInput.FirstNameAsc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users filtered by + args.where === { id_not_in: [testUsers[2]._id], firstName_not_in: [testUsers[2].firstName], + lastName_not_in: [testUsers[2].lastName], email_not_in: [testUsers[2].email], + appLanguageCode_not_in: [testUsers[2].appLanguageCode] } and + sorted by args.orderBy === 'FirstNameDesc'`, async () => { + const where = { + _id: { + $nin: [testUsers[2]._id], + }, + firstName: { + $nin: [testUsers[2].firstName], + }, + lastName: { + $nin: [testUsers[2].lastName], + }, + email: { + $nin: [testUsers[2].email], + }, + appLanguageCode: { + $nin: [testUsers[2].appLanguageCode], + }, + }; + + const sort = { + firstName: -1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: { + id_not_in: [testUsers[2]._id], + firstName_not_in: [testUsers[2].firstName], + lastName_not_in: [testUsers[2].lastName], + email_not_in: [testUsers[2].email], + appLanguageCode_not_in: [testUsers[2].appLanguageCode], + }, + orderBy: UserOrderByInput.FirstNameDesc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users filtered by + args.where === { firstName_contains: testUsers[1].firstName, + lastName_contains: testUsers[1].lastName, email_contains: testUsers[1].email, + appLanguageCode_contains: testUsers[1].appLanguageCode } and + sorted by args.orderBy === 'lastName_ASC'`, async () => { + const where = { + firstName: { + $regex: testUsers[1].firstName, + $options: "i", + }, + lastName: { + $regex: testUsers[1].lastName, + $options: "i", + }, + email: { + $regex: testUsers[1].email, + $options: "i", + }, + appLanguageCode: { + $regex: testUsers[1].appLanguageCode, + $options: "i", + }, + }; + + const sort = { + lastName: 1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: { + firstName_contains: testUsers[1].firstName, + lastName_contains: testUsers[1].lastName, + email_contains: testUsers[1].email, + appLanguageCode_contains: testUsers[1].appLanguageCode, + }, + orderBy: UserOrderByInput.LastNameAsc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users filtered by + args.where === { firstName_starts_with: testUsers[1].firstName, + lastName_starts_with: testUsers[1].lastName, email_starts_with: testUsers[1].email, + appLanguageCode_starts_with: testUsers[1].appLanguageCode } and + sorted by args.orderBy === 'lastName_DESC'`, async () => { + const where = { + firstName: new RegExp("^" + testUsers[1].firstName), + lastName: new RegExp("^" + testUsers[1].lastName), + email: new RegExp("^" + testUsers[1].email), + appLanguageCode: new RegExp("^" + testUsers[1].appLanguageCode), + }; + + const sort = { + lastName: -1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: { + firstName_starts_with: testUsers[1].firstName, + lastName_starts_with: testUsers[1].lastName, + email_starts_with: testUsers[1].email, + appLanguageCode_starts_with: testUsers[1].appLanguageCode, + }, + orderBy: UserOrderByInput.LastNameDesc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users sorted by + args.orderBy === 'appLanguageCode_ASC'`, async () => { + const where = {}; + + const sort = { + appLanguageCode: 1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: null, + orderBy: UserOrderByInput.AppLanguageCodeAsc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users sorted by + args.orderBy === 'appLanguageCode_DESC'`, async () => { + const where = {}; + + const sort = { + appLanguageCode: -1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: null, + orderBy: UserOrderByInput.AppLanguageCodeDesc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users + sorted by args.orderBy === 'email_ASC'`, async () => { + const where = {}; + + const sort = { + email: 1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: null, + orderBy: UserOrderByInput.EmailAsc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users + sorted by args.orderBy === 'email_DESC'`, async () => { + const where = {}; + + const sort = { + email: -1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: null, + orderBy: UserOrderByInput.EmailDesc, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users sorted by 'email_DESC' if + args.orderBy === undefined`, async () => { + const where = {}; + + const sort = { + email: -1, + }; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: null, + orderBy: undefined, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); + + it(`returns paginated list of users without sorting if orderBy === null`, async () => { + const where = {}; + + const sort = {}; + + const args: QueryUsersConnectionArgs = { + first: 2, + skip: 1, + where: null, + orderBy: null, + }; + + const usersConnectionPayload = await usersConnectionResolver?.( + {}, + args, + {} + ); + + const users = await User.find(where) + .limit(2) + .skip(1) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + expect(usersConnectionPayload).toEqual(users); + }); +}); diff --git a/codegen.yml b/codegen.yml new file mode 100644 index 0000000000..938ea1c89d --- /dev/null +++ b/codegen.yml @@ -0,0 +1,46 @@ +# overwrites the already existing/generated graphql typescript definitions +overwrite: true +# address to the graphql type defintions(schema) +schema: + - "./src/lib/typeDefs/**/*.ts" + # Upload scalar is injected by apollo-server into the schema. Graphql-codegen by default generates it's typescript type as 'any'. + - scalar Upload +generates: + # where to emit the generated graphql typescript defintions + ./src/generated/graphqlCodegen.ts: + plugins: + # Generates base typescript types from graphql types. + - typescript + # Generates resolver types using base typescript types generated above. + - typescript-resolvers + config: + # Makes the info argument passed to the resolver functions optional + optionalInfoArgument: true + # Makes the resolver function callable + makeResolverTypeCallable: true + # Mappers lets us provide database model types to be used in generated typescript types instead of graphql types. This + # is because what we retrieve from the database and what we choose to return from a graphql server could be completely + # different fields. This also helps in seperating out resolver logic for nested relation fields into their own resolvers + # instead of resolving them in the root resolver itself. + mappers: + MessageChat: "../lib/models/MessageChat#Interface_MessageChat" + Comment: "../lib/models/Comment#Interface_Comment" + DirectChat: "../lib/models/DirectChat#Interface_DirectChat" + DirectChatMessage: "../lib/models/DirectChatMessage#Interface_DirectChatMessage" + Donation: "../lib/models/Donation#Interface_Donation" + Event: "../lib/models/Event#Interface_Event" + # EventProject: '../lib/models/EventProject#Interface_EventProject' + # File: '../lib/models/File#Interface_File' + Group: "../lib/models/Group#Interface_Group" + GroupChat: "../lib/models/GroupChat#Interface_GroupChat" + GroupChatMessage: "../lib/models/GroupChatMessage#Interface_GroupChatMessage" + # ImageHash: '../lib/models/ImageHash#Interface_ImageHash' + Language: "../lib/models/Language#Interface_Language" + MembershipRequest: "../lib/models/MembershipRequest#Interface_MembershipRequest" + Message: "../lib/models/Message#Interface_Message" + Organization: "../lib/models/Organization#Interface_Organization" + Plugin: "../lib/models/Plugin#Interface_Plugin" + PluginField: "../lib/models/PluginField#Interface_PluginField" + Post: "../lib/models/Post#Interface_Post" + Task: "../lib/models/Task#Interface_Task" + User: "../lib/models/User#Interface_User" diff --git a/constants.js b/constants.js deleted file mode 100644 index 3126391065..0000000000 --- a/constants.js +++ /dev/null @@ -1,174 +0,0 @@ -let URL = 'http://calico.palisadoes.org/talawa/graphql'; -const USER_NOT_AUTHORIZED = - 'User is not authorized for performing this operation'; -const USER_NOT_AUTHORIZED_MESSAGE = 'user.notAuthorized'; -const USER_NOT_AUTHORIZED_CODE = 'user.notAuthorized'; -const USER_NOT_AUTHORIZED_PARAM = 'user'; - -const USER_ALREADY_MEMBER = 'User is already a member'; -const USER_ALREADY_MEMBER_MESSAGE = 'user.alreadyMember'; -const USER_ALREADY_MEMBER_CODE = 'user.alreadyMember'; -const USER_ALREADY_MEMBER_PARAM = 'user'; - -const MEMBERSHIP_REQUEST_NOT_FOUND = 'Membership Request not found'; -const MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE = 'membershipRequest.notFound'; -const MEMBERSHIP_REQUEST_NOT_FOUND_CODE = 'membershipRequest.notFound'; -const MEMBERSHIP_REQUEST_NOT_FOUND_PARAM = 'membershipRequest'; - -const USER_NOT_FOUND = 'User not found'; -const USER_NOT_FOUND_MESSAGE = 'user.notFound'; -const USER_NOT_FOUND_CODE = 'user.notFound'; -const USER_NOT_FOUND_PARAM = 'user'; - -const ORGANIZATION_NOT_FOUND = 'Organization not found'; -const ORGANIZATION_NOT_FOUND_MESSAGE = 'organization.notFound'; -const ORGANIZATION_NOT_FOUND_CODE = 'organization.notFound'; -const ORGANIZATION_NOT_FOUND_PARAM = 'organization'; - -const ORGANIZATION_MEMBER_NOT_FOUND = "Organization's user is not a member"; -const ORGANIZATION_MEMBER_NOT_FOUND_MESSAGE = 'organization.member.notFound'; -const ORGANIZATION_MEMBER_NOT_FOUND_CODE = 'organization.member.notFound'; -const ORGANIZATION_MEMBER_NOT_FOUND_PARAM = 'organizationMember'; - -const CHAT_NOT_FOUND = 'Chat not found'; -const CHAT_NOT_FOUND_MESSAGE = 'chat.notFound'; -const CHAT_NOT_FOUND_CODE = 'chat.notFound'; -const CHAT_NOT_FOUND_PARAM = 'chat'; - -const EVENT_PROJECT_NOT_FOUND = 'EventProject not found'; -const EVENT_PROJECT_NOT_FOUND_CODE = 'eventProject.notFound'; -const EVENT_PROJECT_NOT_FOUND_MESSAGE = 'eventProject.notFound'; -const EVENT_PROJECT_NOT_FOUND_PARAM = 'eventProject'; - -const EVENT_NOT_FOUND = 'Event not found'; -const EVENT_NOT_FOUND_MESSAGE = 'event.notFound'; -const EVENT_NOT_FOUND_CODE = 'event.notFound'; -const EVENT_NOT_FOUND_PARAM = 'event'; - -const ERROR_IN_SENDING_MAIL = 'Error in sending mail'; - -const INVALID_OTP = 'Invalid OTP'; - -const REGISTRANT_ALREADY_EXIST = 'Already registered for the event'; -const REGISTRANT_ALREADY_EXIST_MESSAGE = 'registrant.alreadyExist'; -const REGISTRANT_ALREADY_EXIST_CODE = 'registrant.alreadyExist'; -const REGISTRANT_ALREADY_EXIST_PARAM = 'registrant'; - -const ORGANIZATION_NOT_AUTHORIZED = 'Organization is not authorized'; -const ORGANIZATION_NOT_AUTHORIZED_MESSAGE = 'org.notAuthorized'; -const ORGANIZATION_NOT_AUTHORIZED_CODE = 'org.notAuthorized'; -const ORGANIZATION_NOT_AUTHORIZED_PARAM = 'org'; - -const MEMBER_NOT_FOUND = 'Member not found'; -const MEMBER_NOT_FOUND_MESSAGE = 'member.notFound'; -const MEMBER_NOT_FOUND_CODE = 'member.notFound'; -const MEMBER_NOT_FOUND_PARAM = 'member'; - -const USER_ALREADY_UNREGISTERED = 'Already registered for the event'; -const USER_ALREADY_UNREGISTERED_MESSAGE = 'registrant.alreadyUnregistered'; -const USER_ALREADY_UNREGISTERED_CODE = 'registrant.alreadyUnregistered'; -const USER_ALREADY_UNREGISTERED_PARAM = 'registrant'; - -const COMMENT_NOT_FOUND = 'Comment not found'; -const COMMENT_NOT_FOUND_MESSAGE = 'comment.notFound'; -const COMMENT_NOT_FOUND_CODE = 'comment.notFound'; -const COMMENT_NOT_FOUND_PARAM = 'comment'; - -const POST_NOT_FOUND = 'Post not found'; -const POST_NOT_FOUND_MESSAGE = 'post.notFound'; -const POST_NOT_FOUND_CODE = 'post.notFound'; -const POST_NOT_FOUND_PARAM = 'post'; - -const STATUS_ACTIVE = 'ACTIVE'; - -const IN_PRODUCTION = process.env.NODE_ENV === 'production'; - -if (process.env.NODE_ENV === 'test') { - URL = 'http://localhost:4000/graphql'; -} - -module.exports = { - STATUS_ACTIVE, - - URL, - IN_PRODUCTION, - - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, - - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, - - EVENT_PROJECT_NOT_FOUND, - EVENT_PROJECT_NOT_FOUND_CODE, - EVENT_PROJECT_NOT_FOUND_MESSAGE, - EVENT_PROJECT_NOT_FOUND_PARAM, - - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_MESSAGE, - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM, - - ERROR_IN_SENDING_MAIL, - - INVALID_OTP, - - USER_ALREADY_MEMBER, - USER_ALREADY_MEMBER_CODE, - USER_ALREADY_MEMBER_MESSAGE, - USER_ALREADY_MEMBER_PARAM, - - MEMBERSHIP_REQUEST_NOT_FOUND, - MEMBERSHIP_REQUEST_NOT_FOUND_CODE, - MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE, - MEMBERSHIP_REQUEST_NOT_FOUND_PARAM, - - REGISTRANT_ALREADY_EXIST, - REGISTRANT_ALREADY_EXIST_CODE, - REGISTRANT_ALREADY_EXIST_MESSAGE, - REGISTRANT_ALREADY_EXIST_PARAM, - - ORGANIZATION_NOT_AUTHORIZED, - ORGANIZATION_NOT_AUTHORIZED_MESSAGE, - ORGANIZATION_NOT_AUTHORIZED_CODE, - ORGANIZATION_NOT_AUTHORIZED_PARAM, - - ORGANIZATION_MEMBER_NOT_FOUND, - ORGANIZATION_MEMBER_NOT_FOUND_MESSAGE, - ORGANIZATION_MEMBER_NOT_FOUND_CODE, - ORGANIZATION_MEMBER_NOT_FOUND_PARAM, - - CHAT_NOT_FOUND, - CHAT_NOT_FOUND_MESSAGE, - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM, - - MEMBER_NOT_FOUND, - MEMBER_NOT_FOUND_MESSAGE, - MEMBER_NOT_FOUND_CODE, - MEMBER_NOT_FOUND_PARAM, - - USER_ALREADY_UNREGISTERED, - USER_ALREADY_UNREGISTERED_MESSAGE, - USER_ALREADY_UNREGISTERED_CODE, - USER_ALREADY_UNREGISTERED_PARAM, - - COMMENT_NOT_FOUND, - COMMENT_NOT_FOUND_MESSAGE, - COMMENT_NOT_FOUND_CODE, - COMMENT_NOT_FOUND_PARAM, - - POST_NOT_FOUND, - POST_NOT_FOUND_MESSAGE, - POST_NOT_FOUND_CODE, - POST_NOT_FOUND_PARAM, -}; diff --git a/db.js b/db.js deleted file mode 100644 index afab53717a..0000000000 --- a/db.js +++ /dev/null @@ -1,21 +0,0 @@ -const mongoose = require('mongoose'); -const logger = require('logger'); - -const connect = async () => { - try { - await mongoose.connect(process.env.MONGO_DB_URL, { - useCreateIndex: true, - useUnifiedTopology: true, - useFindAndModify: false, - useNewUrlParser: true, - }); - } catch (error) { - logger.error('Error while connecting to mongo database', error); - process.exit(1); - } -}; - -const disconnect = async () => { - await mongoose.connection.close(); -}; -module.exports = { connect, disconnect }; diff --git a/docker-compose.yml b/docker-compose.yml index 2a478ff90d..37534c267c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,71 @@ -version: '3' +# Version of docker-compose. +version: '3.9' + services: - app: - container_name: talawa-api + # Name of database service. + talawa_mongodb_service: + # Name of the created database container. + container_name: talawa_mongodb + + # Image used for creating the database container. + # More about it here:- https://hub.docker.com/_/mongo. + image: mongo + + # Maps port 27017 of host system to port 27017 of container. MongoDB by default + # runs on port 27017. So, inside the container it runs on port 27017 and + # after mapping it's accessible on port 27017 on the host system as well. + ports: + - 27017:27017 + + # Restarts the container automatically. restart: always + + # Mounts the data created/stored in container's file system to a host + # system's volume which is managed by docker. This prevents data deletion + # if the container is stopped/deleted/rebuilt. To delete the volume as + # well use 'docker rm -v container_id' command. This is called + # 'named volume' approach to persisting data with docker. + volumes: + - talawa_mongodb:/data/db + + # Name of api service. + talawa_api_service: + # Name of the created api(server) container. + container_name: talawa_api + + # Tells docker-compose the location of Dockerfile. build: . + + # Maps port 4000 of host system to port 4000 of container. In + # development environment talawa-api runs on port 4000. So, inside + # the container it runs on port 4000 and after mapping it's + # accessible on port 4000 on the host system as well. ports: - - '4000:4000' - links: - - mongo - environment: - ACCESS_TOKEN_SECRET: "${ACCESS_TOKEN_SECRET}" - REFRESH_TOKEN_SECRET: "${REFRESH_TOKEN_SECRET}" - MONGO_DB_URL: "${MONGO_DB_URL}" - mongo: - image: mongo - ports: - - '27017:27017' \ No newline at end of file + - 4000:4000 + + # Restarts the container automatically. + restart: always + + volumes: + # Mounts current directory to '/usr/src/app' directory of container. + # This will keep the files in current directory in sync with container + # files and any changes made to these files on host system will be reflected + # inside the container. This is useful for a development environment. + # This is called the 'bind mount' approach to persisting data with docker. + - .:/usr/src/app + + # We don't want to sync node_modules folder between the host system and container. + # It should be updated by rebuilding the image. '.:/usr/src/app' mounts + # everything present in current host system directory to 'WORKDIR' inside + # container. But '/usr/src/app/node_modules' maps an empty address to node_modules + # folder inside the container. Therefore, providing a more specific instruction to docker + # to ignore node_modules. + - /usr/src/app/node_modules + + # Makes this service dependent on 'talawa_mongodb_service'. Docker will make sure + # that 'talawa_mongodb_service' is active/online before running 'talawa_api_service'. + depends_on: + - talawa_mongodb_service + +volumes: + talawa_mongodb: {} diff --git a/image/README.md b/image/README.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/index.js b/index.js deleted file mode 100644 index 07b60698c7..0000000000 --- a/index.js +++ /dev/null @@ -1,192 +0,0 @@ -require('dotenv').config(); // pull env variables from .env file - -const depthLimit = require('graphql-depth-limit'); -const { ApolloServer, PubSub } = require('apollo-server-express'); -const http = require('http'); -const rateLimit = require('express-rate-limit'); -const xss = require('xss-clean'); -const helmet = require('helmet'); -const mongoSanitize = require('express-mongo-sanitize'); -const jwt = require('jsonwebtoken'); -const express = require('express'); -const cors = require('cors'); -const logger = require('logger'); -const requestLogger = require('morgan'); -const path = require('path'); -const i18n = require('i18n'); -const requestContext = require('talawa-request-context'); -const requestTracing = require('request-tracing'); - -const Query = require('./lib/resolvers/Query'); -const Mutation = require('./lib/resolvers/Mutation'); -const typeDefs = require('./lib/schema/schema.graphql'); -const isAuth = require('./lib/middleware/is-auth'); -const database = require('./db.js'); -const Organization = require('./lib/resolvers/Organization'); -const MembershipRequest = require('./lib/resolvers/MembershipRequest'); -const DirectChat = require('./lib/resolvers/DirectChat'); -const DirectChatMessage = require('./lib/resolvers/DirectChatMessage'); -const { defaultLocale, supportedLocales } = require('./lib/config/app'); -const GroupChat = require('./lib/resolvers/GroupChat'); -const GroupChatMessage = require('./lib/resolvers/GroupChatMessage'); -const Subscription = require('./lib/resolvers/Subscription'); -const AuthenticationDirective = require('./lib/directives/authDirective'); -const RoleAuthorizationDirective = require('./lib/directives/roleDirective'); - -const app = express(); - -app.use(requestTracing.middleware()); - -const pubsub = new PubSub(); - -const resolvers = { - Subscription: Subscription, - Query, - Mutation, - Organization, - MembershipRequest, - DirectChat, - DirectChatMessage, - GroupChat, - GroupChatMessage, -}; - -const apiLimiter = rateLimit({ - windowMs: 60 * 60 * 1000, - max: 50000, - message: 'Too many requests from this IP, please try again after 15 minutes', -}); - -i18n.configure({ - directory: `${__dirname}/locales`, - staticCatalog: { - en: require('./locales/en.json'), - hi: require('./locales/hi.json'), - zh: require('./locales/zh.json'), - sp: require('./locales/sp.json'), - fr: require('./locales/fr.json'), - }, - queryParameter: 'lang', - defaultLocale: defaultLocale, - locales: supportedLocales, - autoReload: process.env.NODE_ENV !== 'production', - updateFiles: process.env.NODE_ENV !== 'production', - syncFiles: process.env.NODE_ENV !== 'production', -}); - -app.use(i18n.init); -app.use(apiLimiter); -app.use(xss()); -app.use( - helmet({ - contentSecurityPolicy: - process.env.NODE_ENV === 'production' ? undefined : false, - }) -); -app.use(mongoSanitize()); -app.use(cors()); -app.use( - requestLogger( - ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms', - { - stream: logger.stream, - } - ) -); -app.use('/images', express.static(path.join(__dirname, './images'))); -app.use(requestContext.middleware()); - -app.get('/', (req, res) => - res.json({ - 'talawa-version': 'v1', - status: 'healthy', - }) -); - -const httpServer = http.createServer(app); - -const apolloServer = new ApolloServer({ - typeDefs, - resolvers, - validationRules: [depthLimit(5)], - schemaDirectives: { - auth: AuthenticationDirective, - role: RoleAuthorizationDirective, - }, - context: ({ req, res, connection }) => { - if (connection) { - return { - ...connection, - pubsub, - res, - req, - }; - } else { - return { - ...isAuth(req), - pubsub, - res, - req, - }; - } - }, - formatError: (err) => { - if (!err.originalError) { - return err; - } - const message = err.message || 'Something went wrong !'; - const data = err.originalError.errors || []; - const code = err.originalError.code || 422; - logger.error(message, err); - return { - message, - status: code, - data, - }; - }, - subscriptions: { - onConnect: (connection) => { - if (!connection.authorization) { - throw new Error('userAuthentication'); - } - let userId = null; - const token = connection.authorization.split(' ')[1]; - if (token) { - let decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); - userId = decodedToken.userId; - } - - return { - currentUserToken: connection, - currentUserId: userId, - }; - }, - }, -}); - -apolloServer.applyMiddleware({ - app, -}); -apolloServer.installSubscriptionHandlers(httpServer); - -const serverStart = async () => { - try { - await database.connect(); - httpServer.listen(process.env.PORT || 4000, () => { - logger.info( - `🚀 Server ready at http://localhost:${process.env.PORT || 4000}${ - apolloServer.graphqlPath - }` - ); - logger.info( - `🚀 Subscriptions ready at ws://localhost:${process.env.PORT || 4000}${ - apolloServer.subscriptionsPath - }` - ); - }); - } catch (e) { - logger.error('Error while connecting to database', e); - } -}; - -serverStart(); diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index e834a9c145..0000000000 --- a/jest.config.js +++ /dev/null @@ -1,10 +0,0 @@ -// in jest.config.js -module.exports = { - // extends time taken before the request times out to 30000ms - testTimeout: 30000, - collectCoverage: true, - testEnvironment: 'node', - coverageDirectory: './coverage/', - collectCoverageFrom: ['lib/**/*.js*'], - coveragePathIgnorePatterns: ['/node_modules/', 'lib/helper_lib'], -}; diff --git a/lib/directives/authDirective.js b/lib/directives/authDirective.js deleted file mode 100644 index 119883e552..0000000000 --- a/lib/directives/authDirective.js +++ /dev/null @@ -1,22 +0,0 @@ -const { SchemaDirectiveVisitor } = require('apollo-server-express'); -const { UnauthenticatedError } = require('errors'); -const { defaultFieldResolver } = require('graphql'); -const requestContext = require('talawa-request-context'); - -class AuthenticationDirective extends SchemaDirectiveVisitor { - visitFieldDefinition(field) { - const resolver = field.resolve || defaultFieldResolver; - field.resolve = async (root, args, context, info) => { - if (context.expired || !context.isAuth) - throw new UnauthenticatedError( - requestContext.translate('user.notAuthenticated'), - 'user.notAuthenticated', - 'userAuthentication' - ); - - return resolver(root, args, context, info); - }; - } -} - -module.exports = AuthenticationDirective; diff --git a/lib/directives/roleDirective.js b/lib/directives/roleDirective.js deleted file mode 100644 index b42067e6e1..0000000000 --- a/lib/directives/roleDirective.js +++ /dev/null @@ -1,29 +0,0 @@ -const { SchemaDirectiveVisitor } = require('apollo-server-express'); -const { UnauthenticatedError } = require('errors'); -const { defaultFieldResolver } = require('graphql'); -const requestContext = require('talawa-request-context'); -const userExists = require('../helper_functions/userExists'); - -class RoleAuthorizationDirective extends SchemaDirectiveVisitor { - visitFieldDefinition(field) { - const resolver = field.resolve || defaultFieldResolver; - const { requires } = this.args; - field.resolve = async (root, args, context, info) => { - const user = await userExists(context.userId); - - if (user.userType !== requires) { - throw new UnauthenticatedError( - requestContext.translate('user.notAuthenticated'), - 'user.notAuthenticated', - 'userAuthentication' - ); - } - - context.user = user; - - return resolver(root, args, context, info); - }; - } -} - -module.exports = RoleAuthorizationDirective; diff --git a/lib/helper_functions/ReuploadDuplicateCheck.js b/lib/helper_functions/ReuploadDuplicateCheck.js deleted file mode 100644 index 3191f478f0..0000000000 --- a/lib/helper_functions/ReuploadDuplicateCheck.js +++ /dev/null @@ -1,35 +0,0 @@ -const { imageHash } = require('image-hash'); -const { ValidationError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (imageJustUploadedPath, itemImage) => { - // This function checks whether a user is trying to re=upload the same profile picture or an org is trying to re-upload the same org image - try { - if (itemImage) { - const getImageHash = (oldSrc) => { - return new Promise((resolve, reject) => { - imageHash(oldSrc, 16, true, (error, data) => { - if (error) reject(error); - resolve(data); - }); - }); - }; - let oldImageHash = await getImageHash(itemImage); - let newImageHash = await getImageHash(imageJustUploadedPath); - return oldImageHash === newImageHash; - } - return false; - } catch (e) { - console.log(e); - throw new ValidationError( - [ - { - message: requestContext.translate('invalid.fileType'), - code: 'invalid.fileType', - param: 'fileType', - }, - ], - requestContext.translate('invalid.fileType') - ); - } -}; diff --git a/lib/helper_functions/auth.js b/lib/helper_functions/auth.js deleted file mode 100644 index e43b0c784b..0000000000 --- a/lib/helper_functions/auth.js +++ /dev/null @@ -1,31 +0,0 @@ -const jwt = require('jsonwebtoken'); - -module.exports.createAccessToken = async (user) => { - const userId = user.id; - return jwt.sign( - { - tokenVersion: user.tokenVersion, - userId, - firstName: user._doc.firstName, - lastName: user._doc.lastName, - email: user._doc.email, - }, - process.env.ACCESS_TOKEN_SECRET, - { expiresIn: '15m' } - ); -}; - -module.exports.createRefreshToken = async (user) => { - const userId = user.id; - return jwt.sign( - { - tokenVersion: user.tokenVersion, - userId, - firstName: user._doc.firstName, - lastName: user._doc.lastName, - email: user._doc.email, - }, - process.env.REFRESH_TOKEN_SECRET, - { expiresIn: '30d' } - ); -}; diff --git a/lib/helper_functions/deleteDuplicatedImage.js b/lib/helper_functions/deleteDuplicatedImage.js deleted file mode 100644 index 233b007eae..0000000000 --- a/lib/helper_functions/deleteDuplicatedImage.js +++ /dev/null @@ -1,10 +0,0 @@ -const { unlink } = require('fs'); -const logger = require('logger'); - -module.exports = function deleteDuplicatedImage(imagePath) { - unlink(imagePath, function (err) { - if (err) throw err; - // if no error, file has been deleted successfully - logger.info('File was deleted as it already exists in the db!'); - }); -}; diff --git a/lib/helper_functions/deleteImage.js b/lib/helper_functions/deleteImage.js deleted file mode 100644 index 662a62820f..0000000000 --- a/lib/helper_functions/deleteImage.js +++ /dev/null @@ -1,52 +0,0 @@ -const { unlink } = require('fs'); -const logger = require('logger'); -const ImageHash = require('../models/ImageHash'); - -const reuploadDuplicateCheck = require('./ReuploadDuplicateCheck'); - -async function deleteImage(imageToBeDeleted, imageBelongingToItem) { - let tryingToReUploadADuplicate; - if (imageBelongingToItem) { - tryingToReUploadADuplicate = await reuploadDuplicateCheck( - imageBelongingToItem, - imageToBeDeleted - ); - } - - if (!tryingToReUploadADuplicate) { - // Only remove the old image if its different from the new one - // Ensure image hash isn't used by multiple users/organization before deleting it - let hash = await ImageHash.findOne({ - fileName: imageToBeDeleted, - }); - - if (hash && hash.numberOfUses > 1) { - // image is only deleted if it is only used once - logger.info('Image cannot be deleted'); - } else { - logger.info('Image is only used once and therefore can be deleted'); - unlink(imageToBeDeleted, function (err) { - if (err) throw err; - // if no error, file has been deleted successfully - logger.info('File deleted!'); - }); - } - - await ImageHash.findOneAndUpdate( - { - // decrement number of uses of hashed image - fileName: imageToBeDeleted, - }, - { - $inc: { - numberOfUses: -1, - }, - }, - { - new: true, - } - ); - } -} - -module.exports = deleteImage; diff --git a/lib/helper_functions/imageAlreadyInDbCheck.js b/lib/helper_functions/imageAlreadyInDbCheck.js deleted file mode 100644 index 74a297fbf8..0000000000 --- a/lib/helper_functions/imageAlreadyInDbCheck.js +++ /dev/null @@ -1,84 +0,0 @@ -const ImageHash = require('../models/ImageHash'); -const { imageHash } = require('image-hash'); -const deleteDuplicatedImage = require('./deleteDuplicatedImage'); -const reuploadDuplicateCheck = require('./ReuploadDuplicateCheck'); -const { ValidationError } = require('errors'); -const requestContext = require('talawa-request-context'); - -// Check to see if image already exists in db using hash -// if its there point to that image and remove the image just uploaded -// if its not there allow the file to remain uploaded -module.exports = async function imageAlreadyInDbCheck( - imageJustUploadedPath, - itemImage -) { - try { - let fileName; - const getImageHash = () => - new Promise((resolve, reject) => { - imageHash(`./${imageJustUploadedPath}`, 16, true, (error, data) => { - if (error) reject(JSON.stringify(error)); - else resolve(data); - }); - }); - const hash = await getImageHash(); - const imageAlreadyExistsInDb = await ImageHash.findOne({ - hashValue: hash, - }); - if (imageAlreadyExistsInDb) { - let tryingToReUploadADuplicate; - tryingToReUploadADuplicate = await reuploadDuplicateCheck( - imageJustUploadedPath, - itemImage - ); - if (!tryingToReUploadADuplicate) { - // dont increment if the same user/org is using the same image multiple times for the same use case - await ImageHash.findOneAndUpdate( - { - // Increase the number of places this image is used - hashValue: hash, - }, - { - $inc: { - numberOfUses: 1, - }, - }, - { - new: true, - } - ); - // console.log( - // "num of uses of hash (old image): " + imageHashObj._doc.numberOfUses - // ); - } - - //console.log("Image already exists in db"); - // remove the image that was just uploaded - deleteDuplicatedImage(imageJustUploadedPath); - - fileName = imageAlreadyExistsInDb._doc.fileName; // will include have file already in db if pic is already saved will be null otherwise - } else { - let hashObj = new ImageHash({ - hashValue: hash, - fileName: imageJustUploadedPath, - numberOfUses: 1, - }); - await hashObj.save(); - // console.log( - // "number of uses of hash (new image) : " + hashObj._doc.numberOfUses - // ); - } - return fileName; - } catch (e) { - throw new ValidationError( - [ - { - message: requestContext.translate('invalid.fileType'), - code: 'invalid.fileType', - param: 'fileType', - }, - ], - requestContext.translate('invalid.fileType') - ); - } -}; diff --git a/lib/helper_functions/imageExtensionCheck.js b/lib/helper_functions/imageExtensionCheck.js deleted file mode 100644 index f3bb9afc5b..0000000000 --- a/lib/helper_functions/imageExtensionCheck.js +++ /dev/null @@ -1,20 +0,0 @@ -const deleteImage = require('./deleteImage'); -const { ValidationError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (filename) => { - const extension = filename.split('.').pop(); - if (extension !== 'png' && extension !== 'jpg' && extension !== 'jpeg') { - await deleteImage(filename); - throw new ValidationError( - [ - { - message: requestContext.translate('invalid.fileType'), - code: 'invalid.fileType', - param: 'fileType', - }, - ], - requestContext.translate('invalid.fileType') - ); - } -}; diff --git a/lib/helper_functions/mailer.js b/lib/helper_functions/mailer.js deleted file mode 100644 index 4aa7d060b3..0000000000 --- a/lib/helper_functions/mailer.js +++ /dev/null @@ -1,33 +0,0 @@ -const nodemailer = require('nodemailer'); - -const { ERROR_IN_SENDING_MAIL } = require('../../constants'); - -const mailer = (email, subject, body) => { - //NODEMAILER SPECIFIC STUFF - let transporter = nodemailer.createTransport({ - service: 'gmail', - auth: { - user: process.env.MAIL_USERNAME, - pass: process.env.MAIL_PASSWORD, - }, - }); - - let mailOptions = { - from: 'Talawa<>noreply@gmail.com', - to: email, - subject: subject, - html: body, - }; - - return new Promise((resolve, reject) => { - transporter.sendMail(mailOptions, function (err, info) { - if (err) { - reject(ERROR_IN_SENDING_MAIL); - } else { - resolve(info); - } - }); - }); -}; - -module.exports = mailer; diff --git a/lib/helper_functions/organizationExists.js b/lib/helper_functions/organizationExists.js deleted file mode 100644 index afbb2b2dae..0000000000 --- a/lib/helper_functions/organizationExists.js +++ /dev/null @@ -1,26 +0,0 @@ -const Organization = require('../models/Organization'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_PARAM, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, -} = require('../../constants'); - -module.exports = async (id) => { - const organization = await Organization.findOne({ - _id: id, - }); - if (!organization) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - return organization; -}; diff --git a/lib/helper_functions/uploadImage.js b/lib/helper_functions/uploadImage.js deleted file mode 100644 index f66f60cfab..0000000000 --- a/lib/helper_functions/uploadImage.js +++ /dev/null @@ -1,48 +0,0 @@ -const shortid = require('shortid'); -const logger = require('logger'); -const { createWriteStream } = require('fs'); -const path = require('path'); -const imageAlreadyInDbCheck = require('./imageAlreadyInDbCheck'); -const deleteImage = require('./deleteImage'); -const imageExtensionCheck = require('./imageExtensionCheck'); - -module.exports = async (file, itemImage) => { - const id = shortid.generate(); - const { createReadStream, filename } = await file; - - // throw an error if file is not png or jpg - await imageExtensionCheck(filename); - - // upload new image - await new Promise((resolve, reject) => - createReadStream() - .pipe( - createWriteStream( - path.join(__dirname, '../images', `/${id}-${filename}`) - ) - ) - .on('close', resolve) - .on('error', (error) => reject(error)) - .on('finish', () => resolve({ path })) - ); - - let imageJustUploadedPath = `images/${id}-${filename}`; - - //return imagePath; - - if (itemImage) { - logger.info('old image should be deleted'); - // If user/org already has an image delete it from the API - await deleteImage(itemImage, imageJustUploadedPath); - } - - let imageAlreadyInDbPath = await imageAlreadyInDbCheck( - imageJustUploadedPath, - itemImage - ); - - return { - newImagePath: imageJustUploadedPath, - imageAlreadyInDbPath: imageAlreadyInDbPath, - }; -}; diff --git a/lib/helper_functions/userExists.js b/lib/helper_functions/userExists.js deleted file mode 100644 index d64c814191..0000000000 --- a/lib/helper_functions/userExists.js +++ /dev/null @@ -1,24 +0,0 @@ -const User = require('../models/User'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, -} = require('../../constants'); - -module.exports = async (id) => { - const user = await User.findOne({ _id: id }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - return user; -}; diff --git a/lib/helper_lib/errors/application-error.js b/lib/helper_lib/errors/application-error.js deleted file mode 100644 index ed0c2cd500..0000000000 --- a/lib/helper_lib/errors/application-error.js +++ /dev/null @@ -1,9 +0,0 @@ -class ApplicationError extends Error { - constructor(errors, httpCode, message) { - super(message || 'Error'); - this.httpCode = httpCode || 422; - this.errors = errors; - } -} - -module.exports = ApplicationError; diff --git a/lib/helper_lib/errors/conflict-error.js b/lib/helper_lib/errors/conflict-error.js deleted file mode 100644 index fba135c3ed..0000000000 --- a/lib/helper_lib/errors/conflict-error.js +++ /dev/null @@ -1,18 +0,0 @@ -const ApplicationError = require('./application-error'); - -class ConflictError extends ApplicationError { - constructor(message, code = null, param = null, metadata = {}) { - const errorMessage = message || 'Conflicting entry found'; - const errorJson = [ - { - message: errorMessage, - code, - param, - metadata, - }, - ]; - super(errorJson, 409, errorMessage); - } -} - -module.exports = ConflictError; diff --git a/lib/helper_lib/errors/index.js b/lib/helper_lib/errors/index.js deleted file mode 100644 index 9849cb5701..0000000000 --- a/lib/helper_lib/errors/index.js +++ /dev/null @@ -1,19 +0,0 @@ -const errors = {}; - -// Base class -errors.ApplicationError = require('./application-error'); - -// Used for server fatal error -errors.InternalServerError = require('./internal-server-error'); -// Used for resource not found -errors.NotFoundError = require('./not-found-error'); -// Used for user is forbidden to perform operation -errors.UnauthorizedError = require('./unauthorized-error'); -// Used for basic sanity checks -errors.ValidationError = require('./validation-error'); -// Used for invalid authentication token or wrong credentials -errors.UnauthenticatedError = require('./unauthenticated-error'); -// Used for resource already present -errors.ConflictError = require('./conflict-error'); - -module.exports = errors; diff --git a/lib/helper_lib/errors/internal-server-error.js b/lib/helper_lib/errors/internal-server-error.js deleted file mode 100644 index b01c68c1a5..0000000000 --- a/lib/helper_lib/errors/internal-server-error.js +++ /dev/null @@ -1,19 +0,0 @@ -const ApplicationError = require('./application-error'); - -class InternalServerError extends ApplicationError { - constructor(message, code = null, param = null, metadata = {}) { - const errorMessage = message || 'Internal Server Error!'; - - const errorJson = [ - { - message: errorMessage, - code, - param, - metadata, - }, - ]; - super(errorJson, 500, errorMessage); - } -} - -module.exports = InternalServerError; diff --git a/lib/helper_lib/errors/not-found-error.js b/lib/helper_lib/errors/not-found-error.js deleted file mode 100644 index 288778d66d..0000000000 --- a/lib/helper_lib/errors/not-found-error.js +++ /dev/null @@ -1,18 +0,0 @@ -const ApplicationError = require('./application-error'); - -class NotFoundError extends ApplicationError { - constructor(message, code = null, param = null, metadata = {}) { - const errorMessage = message || 'Not Found'; - const errorJson = [ - { - message: errorMessage, - code, - param, - metadata, - }, - ]; - super(errorJson, 404, errorMessage); - } -} - -module.exports = NotFoundError; diff --git a/lib/helper_lib/errors/package.json b/lib/helper_lib/errors/package.json deleted file mode 100644 index 8c73a939d6..0000000000 --- a/lib/helper_lib/errors/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "errors", - "version": "1.0.0", - "description": "Error classes for nodejs", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Palisadoes Foundation", - "license": "GNU General Public License v3.0", - "bugs": { - "url": "https://github.com/PalisadoesFoundation/talawa-api/issues" - }, - "dependencies": { - } -} diff --git a/lib/helper_lib/errors/unauthenticated-error.js b/lib/helper_lib/errors/unauthenticated-error.js deleted file mode 100644 index 0e8ef7a985..0000000000 --- a/lib/helper_lib/errors/unauthenticated-error.js +++ /dev/null @@ -1,18 +0,0 @@ -const ApplicationError = require('./application-error'); - -class UnauthenticatedError extends ApplicationError { - constructor(message, code = null, param = null, metadata = {}) { - const errorMessage = message || 'UnauthenticatedError'; - const errorJson = [ - { - message: errorMessage, - code, - param, - metadata, - }, - ]; - super(errorJson, 401, errorMessage); - } -} - -module.exports = UnauthenticatedError; diff --git a/lib/helper_lib/errors/unauthorized-error.js b/lib/helper_lib/errors/unauthorized-error.js deleted file mode 100644 index 6a58bcde60..0000000000 --- a/lib/helper_lib/errors/unauthorized-error.js +++ /dev/null @@ -1,18 +0,0 @@ -const ApplicationError = require('./application-error'); - -class UnauthorizedError extends ApplicationError { - constructor(message, code = null, param = null, metadata = {}) { - const errorMessage = message || 'UnauthorizedError'; - const errorJson = [ - { - message: errorMessage, - code, - param, - metadata, - }, - ]; - super(errorJson, 403, errorMessage); - } -} - -module.exports = UnauthorizedError; diff --git a/lib/helper_lib/errors/validation-error.js b/lib/helper_lib/errors/validation-error.js deleted file mode 100644 index c3b67e9592..0000000000 --- a/lib/helper_lib/errors/validation-error.js +++ /dev/null @@ -1,9 +0,0 @@ -const ApplicationError = require('./application-error'); - -class ValidationError extends ApplicationError { - constructor(errors, message) { - super(errors || [], 422, message || 'Validation error'); - } -} - -module.exports = ValidationError; diff --git a/lib/helper_lib/index.js b/lib/helper_lib/index.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lib/helper_lib/logger/index.js b/lib/helper_lib/logger/index.js deleted file mode 100644 index c8ab6ddedd..0000000000 --- a/lib/helper_lib/logger/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./logger'); diff --git a/lib/helper_lib/logger/logger.js b/lib/helper_lib/logger/logger.js deleted file mode 100644 index dade3e0c69..0000000000 --- a/lib/helper_lib/logger/logger.js +++ /dev/null @@ -1,56 +0,0 @@ -const { createLogger, transports, format } = require('winston'); -const requestTracing = require('request-tracing'); -const _ = require('lodash'); - -const appConfig = require('../../config/app'); - -const { combine, printf, splat, colorize, simple, timestamp } = format; - -const loggerFormat = printf((info) => { - let formatObject = `${info.level || '-'} ${info.timestamp || '-'} ${ - requestTracing.getTracingId() || '-' - } ${info.message} ${ - JSON.stringify(_.omit(info, ['level', 'message', 'stack', 'timestamp'])) || - '-' - }`; - - if (info.stack) { - formatObject += `\n${info.stack}`; - } - return formatObject; -}); - -const formats = { - colorized: combine( - colorize(), - splat(), - simple(), - timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), - loggerFormat - ), - non_colorized: combine( - splat(), - simple(), - timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), - loggerFormat - ), -}; - -const logger = createLogger({ - transports: [ - new transports.Console({ - level: appConfig.log_level, - format: - appConfig.colorize_logs === 'true' - ? formats.colorized - : formats.non_colorized, - }), - ], -}); - -logger.stream = { - write: (message) => { - logger.info((message || '').trim()); - }, -}; -module.exports = logger; diff --git a/lib/helper_lib/logger/package.json b/lib/helper_lib/logger/package.json deleted file mode 100644 index 7bc2ef3332..0000000000 --- a/lib/helper_lib/logger/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "logger", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Palisadoes Foundation", - "license": "GNU General Public License v3.0", - "dependencies": { - "lodash": "^4.17.21", - "winston": "^3.3.3" - } -} diff --git a/lib/helper_lib/request-tracing/index.js b/lib/helper_lib/request-tracing/index.js deleted file mode 100644 index 05e6102ffc..0000000000 --- a/lib/helper_lib/request-tracing/index.js +++ /dev/null @@ -1,53 +0,0 @@ -const cls = require('cls-hooked'); -const clsBluebird = require('cls-bluebird'); -const { customAlphabet } = require('nanoid'); - -const alphabet = '0123456789abcdefghijklmnopqrstuvwxyz'; - -const requestTracingNamespace = cls.createNamespace('request-tracing'); -clsBluebird(requestTracingNamespace); - -const tracingIdHeaderName = 'X-Tracing-Id'; -const tracingIdContextKeyName = 'tracingId'; - -const nanoid = customAlphabet(alphabet, 10); -const _newTraceId = () => nanoid(); // 10 character unique request ID - -const setTracingId = (tracingId) => { - return requestTracingNamespace.set(tracingIdContextKeyName, tracingId); -}; - -const getTracingId = () => { - return requestTracingNamespace.get(tracingIdContextKeyName); -}; - -const middleware = () => { - return (req, res, next) => { - requestTracingNamespace.bindEmitter(req); - requestTracingNamespace.bindEmitter(res); - - const tracingId = req.header(tracingIdHeaderName) || _newTraceId(); - // We need to set header to ensure API gateway which proxies request, forwards the header as well - req.headers[tracingIdHeaderName] = tracingId; - res.header(tracingIdHeaderName, tracingId); // Adding tracing ID to response headers - - requestTracingNamespace.run(() => { - setTracingId(tracingId); - next(); - }); - }; -}; - -const trace = async (tracingId, method) => { - await requestTracingNamespace.runAndReturn(async () => { - setTracingId(tracingId || _newTraceId()); - return method(); - }); -}; - -module.exports = { - middleware, - trace, - getTracingId, - tracingIdHeaderName, -}; diff --git a/lib/helper_lib/request-tracing/package-lock.json b/lib/helper_lib/request-tracing/package-lock.json deleted file mode 100644 index 7598885f03..0000000000 --- a/lib/helper_lib/request-tracing/package-lock.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "name": "request-tracing", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "request-tracing", - "version": "1.0.0", - "license": "GNU General Public License v3.0", - "dependencies": { - "cls-bluebird": "^2.1.0", - "cls-hooked": "^4.2.2", - "nanoid": "^3.1.31" - } - }, - "node_modules/async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "dependencies": { - "stack-chain": "^1.3.7" - }, - "engines": { - "node": "^4.7 || >=6.9 || >=7.3" - } - }, - "node_modules/cls-bluebird": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", - "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", - "dependencies": { - "is-bluebird": "^1.0.2", - "shimmer": "^1.1.0" - } - }, - "node_modules/cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "dependencies": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, - "engines": { - "node": "^4.7 || >=6.9 || >=7.3 || >=8.2.1" - } - }, - "node_modules/emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "dependencies": { - "shimmer": "^1.2.0" - } - }, - "node_modules/is-bluebird": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", - "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanoid": { - "version": "3.1.31", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.31.tgz", - "integrity": "sha512-ZivnJm0o9bb13p2Ot5CpgC2rQdzB9Uxm/mFZweqm5eMViqOJe3PV6LU2E30SiLgheesmcPrjquqraoolONSA0A==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "node_modules/stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - } - }, - "dependencies": { - "async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", - "requires": { - "stack-chain": "^1.3.7" - } - }, - "cls-bluebird": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", - "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", - "requires": { - "is-bluebird": "^1.0.2", - "shimmer": "^1.1.0" - } - }, - "cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "requires": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - } - }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, - "is-bluebird": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", - "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" - }, - "nanoid": { - "version": "3.1.31", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.31.tgz", - "integrity": "sha512-ZivnJm0o9bb13p2Ot5CpgC2rQdzB9Uxm/mFZweqm5eMViqOJe3PV6LU2E30SiLgheesmcPrjquqraoolONSA0A==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "stack-chain": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" - } - } -} diff --git a/lib/helper_lib/request-tracing/package.json b/lib/helper_lib/request-tracing/package.json deleted file mode 100644 index a673c05e1b..0000000000 --- a/lib/helper_lib/request-tracing/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "request-tracing", - "version": "1.0.0", - "description": "Request tracing used for Talawa API", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Palisadoes Foundation", - "license": "GNU General Public License v3.0", - "bugs": { - "url": "https://github.com/PalisadoesFoundation/talawa-api/issues" - }, - "dependencies": { - "cls-bluebird": "^2.1.0", - "cls-hooked": "^4.2.2", - "nanoid": "^3.1.31" - } -} diff --git a/lib/helper_lib/talawa-request-context/index.js b/lib/helper_lib/talawa-request-context/index.js deleted file mode 100644 index 3c65bb2465..0000000000 --- a/lib/helper_lib/talawa-request-context/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./talawa-request-context'); diff --git a/lib/helper_lib/talawa-request-context/package.json b/lib/helper_lib/talawa-request-context/package.json deleted file mode 100644 index 3319963a03..0000000000 --- a/lib/helper_lib/talawa-request-context/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "talawa-request-context", - "version": "1.0.0", - "description": "Request Context used for Talawa API", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Palisadoes Foundation", - "license": "GNU General Public License v3.0", - "bugs": { - "url": "https://github.com/PalisadoesFoundation/talawa-api/issues" - }, - "dependencies": { - "cls-bluebird": "^2.1.0", - "cls-hooked": "^4.2.2", - "i18n": "^0.13.3" - } -} diff --git a/lib/helper_lib/talawa-request-context/talawa-request-context.js b/lib/helper_lib/talawa-request-context/talawa-request-context.js deleted file mode 100644 index caf73e8feb..0000000000 --- a/lib/helper_lib/talawa-request-context/talawa-request-context.js +++ /dev/null @@ -1,67 +0,0 @@ -const cls = require('cls-hooked'); -const clsBluebird = require('cls-bluebird'); -const i18n = require('i18n'); - -const requestContextNamespace = cls.createNamespace('talawa-request-context'); -clsBluebird(requestContextNamespace); - -const setRequestContextValue = (key, value) => { - return requestContextNamespace.set(key, value); -}; - -const getRequestContextValue = (key) => { - return requestContextNamespace.get(key); -}; - -const setRequestContext = (obj) => { - setRequestContextValue('translate', obj.__); - setRequestContextValue('translatePlural', obj.__n); -}; - -const middleware = () => { - return (req, res, next) => { - requestContextNamespace.bindEmitter(req); - requestContextNamespace.bindEmitter(res); - - requestContextNamespace.run(() => { - setRequestContext(req); - next(); - }); - }; -}; - -const init = async (options = {}) => { - const obj = {}; - i18n.init(obj); - obj.setLocale(options.lang); - return requestContextNamespace.runAndReturn(async () => { - setRequestContext({ - __: obj.__, - __n: obj.__n, - }); - return options.requestHandler(); - }); -}; - -const translate = (...args) => { - const __ = getRequestContextValue('translate'); - if (typeof __ !== 'function') { - throw new Error('i18n is not initialized, try app.use(i18n.init);'); - } - return __(...args); -}; - -const translatePlural = (...args) => { - const __n = getRequestContextValue('translatePlural'); - if (typeof __n !== 'function') { - throw new Error('i18n is not initialized, try app.use(i18n.init);'); - } - return __n(...args); -}; - -module.exports = { - middleware, - translate, - translatePlural, - init, -}; diff --git a/lib/middleware/is-auth.js b/lib/middleware/is-auth.js deleted file mode 100644 index 2523681cd0..0000000000 --- a/lib/middleware/is-auth.js +++ /dev/null @@ -1,80 +0,0 @@ -const jwt = require('jsonwebtoken'); -const logger = require('logger'); - -const isAuth = (req) => { - // This checks to see if there is an authorization field within the incoming request - const authHeader = req.headers.authorization; - - // if there is no token - if (!authHeader) { - const isAuth = false; - return { - isAuth, - }; - } - - // format of request sent will be Bearer tokenvalue - // this splits it into two values bearer and the token - const token = authHeader.split(' ')[1]; - - // if the token is null or an empty string - if (!token || token === '') { - const isAuth = false; - return { - isAuth, - }; - } - // uses key created in the auth resolver - // to be changed in production - // only tokens created with this key will be valid tokens - let decodedToken; - let expired = false; - try { - decodedToken = jwt.verify( - token, - process.env.ACCESS_TOKEN_SECRET, - (err, decoded) => { - if (err) { - return err; - } - return decoded; - } - ); // If there is an error decoded token would contain it - - if (decodedToken.name === 'TokenExpiredError') { - // If the token has expired set the expired value to true and return it - expired = true; - const isAuth = false; - return { - isAuth, - expired, - }; - } - } catch (e) { - const isAuth = false; - return { - isAuth, - expired, - }; - } - - // if the decoded token is not set - if (!decodedToken) { - logger.info('decoded token is not present'); - const isAuth = false; - return { - isAuth, - }; - } - - // shows the user is an authenticated user - const isAuth = true; - // pulls data off the token - const { userId } = decodedToken; - - return { - isAuth, - userId, - }; -}; -module.exports = isAuth; diff --git a/lib/models/Chat.js b/lib/models/Chat.js deleted file mode 100644 index 7a710dff57..0000000000 --- a/lib/models/Chat.js +++ /dev/null @@ -1,31 +0,0 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; - -const chatSchema = new Schema({ - message: { - type: String, - required: true, - }, - languageBarrier: { - type: Boolean, - required: false, - default: false, - }, - sender: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - receiver: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - createdAt: { - type: Date, - required: true, - default: Date.now, - }, -}); - -module.exports = mongoose.model('MessageChat', chatSchema); diff --git a/lib/models/Comment.js b/lib/models/Comment.js deleted file mode 100644 index 332dd1dfb2..0000000000 --- a/lib/models/Comment.js +++ /dev/null @@ -1,42 +0,0 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; - -//this is the Structure of the Comments -const commentSchema = new Schema({ - text: { - type: String, - required: true, - }, - createdAt: { - type: Date, - default: Date.now, - }, - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - post: { - type: Schema.Types.ObjectId, - ref: 'Post', - required: true, - }, - likedBy: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - }, - ], - likeCount: { - type: Number, - default: 0, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('Comment', commentSchema); diff --git a/lib/models/DirectChat.js b/lib/models/DirectChat.js deleted file mode 100644 index c9af19d5ae..0000000000 --- a/lib/models/DirectChat.js +++ /dev/null @@ -1,38 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -//this is the Structure of the direct chat -const directChatSchema = new Schema({ - users: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - ], - messages: [ - { - type: Schema.Types.ObjectId, - ref: 'DirectChatMessage', - }, - ], - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - organization: { - type: Schema.Types.ObjectId, - ref: 'Organization', - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('DirectChat', directChatSchema); diff --git a/lib/models/DirectChatMessage.js b/lib/models/DirectChatMessage.js deleted file mode 100644 index cbeae1561f..0000000000 --- a/lib/models/DirectChatMessage.js +++ /dev/null @@ -1,38 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -//this is the Structure of the Direct chats -const directChatMessageSchema = new Schema({ - directChatMessageBelongsTo: { - type: Schema.Types.ObjectId, - ref: 'DirectChat', - required: true, - }, - sender: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - receiver: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - createdAt: { - type: Date, - required: true, - }, - messageContent: { - type: String, - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('DirectChatMessage', directChatMessageSchema); diff --git a/lib/models/Event.js b/lib/models/Event.js deleted file mode 100644 index 72f1d71f0a..0000000000 --- a/lib/models/Event.js +++ /dev/null @@ -1,132 +0,0 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; -const User = require('./User'); -const Task = require('./Task'); - -const UserAttende = new Schema({ - userId: { - type: String, - required: true, - }, - user: { - type: Schema.Types.ObjectId, - ref: User, - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, - createdAt: { - type: Date, - default: Date.now, - }, -}); - -//this is the Structure of the event -const eventSchema = new Schema({ - title: { - type: String, - required: true, - }, - description: { - type: String, - required: true, - }, - attendees: { - type: String, - required: false, - }, - location: { - type: String, - }, - latitude: { - type: Number, - required: false, - }, - longitude: { - type: Number, - required: false, - }, - recurring: { - type: Boolean, - required: true, - default: false, - }, - allDay: { - type: Boolean, - required: true, - }, - startDate: { - type: String, - required: true, - }, - endDate: { - type: String, - required: function () { - return !this.allDay; - }, - }, - startTime: { - type: String, - required: function () { - return !this.allDay; - }, - }, - endTime: { - type: String, - required: function () { - return !this.allDay; - }, - }, - recurrance: { - type: String, - default: 'ONCE', - enum: ['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY', 'ONCE'], - required: function () { - return this.recurring; - }, - }, - isPublic: { - type: Boolean, - required: true, - }, - isRegisterable: { - type: Boolean, - required: true, - }, - creator: { - type: Schema.Types.ObjectId, - ref: User, - required: true, - }, - registrants: [UserAttende], - admins: [ - { - type: Schema.Types.ObjectId, - ref: User, - required: true, - }, - ], - organization: { - type: Schema.Types.ObjectId, - ref: 'Organization', - required: true, - }, - tasks: [ - { - type: Schema.Types.ObjectId, - ref: Task, - }, - ], - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('Event', eventSchema); diff --git a/lib/models/EventProject.js b/lib/models/EventProject.js deleted file mode 100644 index 8b2b4d5e64..0000000000 --- a/lib/models/EventProject.js +++ /dev/null @@ -1,43 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -//this is the Structure of the event project -const eventProjectSchema = new Schema({ - title: { - type: String, - required: true, - }, - description: { - type: String, - required: true, - }, - createdAt: { - type: Date, - default: Date.now, - }, - event: { - type: Schema.Types.ObjectId, - ref: 'Event', - required: true, - }, - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - tasks: [ - { - type: Schema.Types.ObjectId, - ref: 'Task', - }, - ], - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('EventProject', eventProjectSchema); diff --git a/lib/models/File.js b/lib/models/File.js deleted file mode 100644 index 028da1d9f0..0000000000 --- a/lib/models/File.js +++ /dev/null @@ -1,37 +0,0 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; -const { v4: uuidv4 } = require('uuid'); - -const fileSchema = new Schema({ - name: { - type: String, - required: true, - default: uuidv4(), - }, - url: { - type: String, - }, - size: { - type: Number, - }, - secret: { - type: String, - required: true, - }, - createdAt: { - type: Date, - required: true, - default: Date.now, - }, - contentType: { - type: String, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('File', fileSchema); diff --git a/lib/models/Group.js b/lib/models/Group.js deleted file mode 100644 index 04edf30deb..0000000000 --- a/lib/models/Group.js +++ /dev/null @@ -1,37 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -const groupSchema = new Schema({ - title: { - type: String, - required: true, - }, - description: { - type: String, - }, - createdAt: { - type: Date, - default: Date.now, - }, - organization: { - type: Schema.Types.ObjectId, - ref: 'Organization', - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, - admins: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - ], -}); - -module.exports = mongoose.model('Group', groupSchema); diff --git a/lib/models/GroupChat.js b/lib/models/GroupChat.js deleted file mode 100644 index f6f67e5449..0000000000 --- a/lib/models/GroupChat.js +++ /dev/null @@ -1,41 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -const groupChatSchema = new Schema({ - title: { - type: String, - required: true, - }, - users: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - ], - messages: [ - { - type: Schema.Types.ObjectId, - ref: 'GroupChatMessage', - }, - ], - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - organization: { - type: Schema.Types.ObjectId, - ref: 'Organization', - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('GroupChat', groupChatSchema); diff --git a/lib/models/GroupChatMessage.js b/lib/models/GroupChatMessage.js deleted file mode 100644 index 5a53391a49..0000000000 --- a/lib/models/GroupChatMessage.js +++ /dev/null @@ -1,32 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -const groupChatMessageSchema = new Schema({ - groupChatMessageBelongsTo: { - type: Schema.Types.ObjectId, - ref: 'GroupChat', - required: true, - }, - sender: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - createdAt: { - type: Date, - required: true, - }, - messageContent: { - type: String, - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('GroupChatMessage', groupChatMessageSchema); diff --git a/lib/models/ImageHash.js b/lib/models/ImageHash.js deleted file mode 100644 index 0c8c07e5b8..0000000000 --- a/lib/models/ImageHash.js +++ /dev/null @@ -1,27 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -const imageHashSchema = new Schema({ - hashValue: { - type: String, - required: true, - }, - fileName: { - type: String, - required: true, - }, - numberOfUses: { - type: Number, - default: 0, - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('ImageHash', imageHashSchema); diff --git a/lib/models/Language.js b/lib/models/Language.js deleted file mode 100644 index 670ed0fd97..0000000000 --- a/lib/models/Language.js +++ /dev/null @@ -1,43 +0,0 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; - -const LangModel = new Schema({ - lang_code: { - type: String, - required: true, - unique: false, - lowercase: true, - }, - value: { - type: String, - required: true, - lowercase: true, - }, - verified: { - type: Boolean, - required: true, - default: false, - }, - createdAt: { - type: Date, - required: true, - default: Date.now, - }, -}); - -const LangSchema = new Schema({ - en: { - type: String, - required: true, - unique: true, - lowercase: true, - }, - translation: [LangModel], - createdAt: { - type: Date, - required: true, - default: Date.now, - }, -}); - -module.exports = mongoose.model('Language', LangSchema); diff --git a/lib/models/MembershipRequest.js b/lib/models/MembershipRequest.js deleted file mode 100644 index e0672ddf9c..0000000000 --- a/lib/models/MembershipRequest.js +++ /dev/null @@ -1,23 +0,0 @@ -const mongoose = require('mongoose'); - -const { Schema } = mongoose; - -const membershipRequestSchema = new Schema({ - organization: { - type: Schema.Types.ObjectId, - ref: 'Organization', - required: true, - }, - user: { - type: Schema.Types.ObjectId, - ref: 'User', - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('MembershipRequest', membershipRequestSchema); diff --git a/lib/models/Message.js b/lib/models/Message.js deleted file mode 100644 index 9c4e7150c5..0000000000 --- a/lib/models/Message.js +++ /dev/null @@ -1,39 +0,0 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; - -const messageSchema = new Schema({ - text: { - type: String, - required: true, - }, - imageUrl: { - type: String, - required: false, - }, - videoUrl: { - type: String, - required: false, - }, - createdAt: { - type: Date, - default: Date.now, - }, - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - group: { - type: Schema.Types.ObjectId, - ref: 'Group', - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, -}); - -module.exports = mongoose.model('Message', messageSchema); diff --git a/lib/models/Organization.js b/lib/models/Organization.js deleted file mode 100644 index 0fad4dd5a5..0000000000 --- a/lib/models/Organization.js +++ /dev/null @@ -1,83 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -const organizationSchema = new Schema({ - apiUrl: { - type: String, - }, - image: { - type: String, - }, - name: { - type: String, - required: true, - }, - description: { - type: String, - required: true, - }, - location: { - type: String, - }, - isPublic: { - type: Boolean, - required: true, - }, - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, - members: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - }, - ], - admins: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - ], - groupChats: [ - { - type: Schema.Types.ObjectId, - ref: 'Message', - }, - ], - posts: [ - { - type: Schema.Types.ObjectId, - ref: 'Post', - }, - ], - membershipRequests: [ - { - type: Schema.Types.ObjectId, - ref: 'MembershipRequest', - }, - ], - blockedUsers: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - }, - ], - visibleInSearch: Boolean, - tags: [], - createdAt: { - type: Date, - default: Date.now, - }, -}); - -module.exports = mongoose.model('Organization', organizationSchema); diff --git a/lib/models/PluginsField.js b/lib/models/PluginsField.js deleted file mode 100644 index c818d7c650..0000000000 --- a/lib/models/PluginsField.js +++ /dev/null @@ -1,26 +0,0 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; - -//this is the Structure of the Comments -const pluginFieldSchema = new Schema({ - key: { - type: String, - required: true, - }, - value: { - type: String, - required: true, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, - createdAt: { - type: Date, - default: Date.now, - }, -}); - -module.exports = mongoose.model('PluginField', pluginFieldSchema); diff --git a/lib/models/Post.js b/lib/models/Post.js deleted file mode 100644 index 2ef30d1693..0000000000 --- a/lib/models/Post.js +++ /dev/null @@ -1,67 +0,0 @@ -/* eslint-disable prettier/prettier */ -const mongoose = require('mongoose'); -const mongoosePaginate = require('mongoose-paginate-v2'); - -const Schema = mongoose.Schema; - -const postSchema = new Schema({ - text: { - type: String, - required: true, - }, - title: { - type: String, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, - createdAt: { - type: Date, - default: Date.now, - }, - imageUrl: { - type: String, - required: false, - }, - videoUrl: { - type: String, - required: false, - }, - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, - organization: { - type: Schema.Types.ObjectId, - ref: 'Organization', - required: true, - }, - likedBy: [ - { - type: Schema.Types.ObjectId, - ref: 'User', - }, - ], - comments: [ - { - type: Schema.Types.ObjectId, - ref: 'Comment', - }, - ], - likeCount: { - type: Number, - default: 0, - }, - commentCount: { - type: Number, - default: 0, - }, -}); - -postSchema.plugin(mongoosePaginate); - -module.exports = mongoose.model('Post', postSchema); diff --git a/lib/models/Task.js b/lib/models/Task.js deleted file mode 100644 index 293bf88bbc..0000000000 --- a/lib/models/Task.js +++ /dev/null @@ -1,33 +0,0 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; - -const taskSchema = new Schema({ - title: { - type: String, - required: true, - }, - description: { - type: String, - }, - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, - createdAt: { type: Date, default: Date.now }, - deadline: { type: Date }, - event: { - type: Schema.Types.ObjectId, - ref: 'Event', - required: true, - }, - creator: { - type: Schema.Types.ObjectId, - ref: 'User', - required: true, - }, -}); - -module.exports = mongoose.model('Task', taskSchema); diff --git a/lib/models/User.js b/lib/models/User.js deleted file mode 100644 index 161f3d8e96..0000000000 --- a/lib/models/User.js +++ /dev/null @@ -1,120 +0,0 @@ -const mongoose = require('mongoose'); -const { isEmail } = require('validator'); -const mongoosePaginate = require('mongoose-paginate-v2'); -const Schema = mongoose.Schema; - -const userSchema = new Schema({ - image: { - type: String, - }, - tokenVersion: { - type: Number, - default: 0, - }, - firstName: { - type: String, - required: true, - }, - token: { - type: String, - required: false, - }, - lastName: { - type: String, - required: true, - }, - email: { - type: String, - validate: [isEmail, 'invalid email'], - required: true, - }, - password: { - type: String, - required: true, - }, - appLanguageCode: { - type: String, - default: 'en', - required: true, - }, - createdOrganizations: [ - { - type: Schema.Types.ObjectId, - ref: 'Organization', - }, - ], - createdEvents: [ - { - type: Schema.Types.ObjectId, - ref: 'Event', - }, - ], - userType: { - type: String, - enum: ['USER', 'ADMIN', 'SUPERADMIN'], - default: 'USER', - required: true, - }, - joinedOrganizations: [ - { - type: Schema.Types.ObjectId, - ref: 'Organization', - }, - ], - registeredEvents: [ - { - type: Schema.Types.ObjectId, - ref: 'Event', - }, - ], - eventAdmin: [ - { - type: Schema.Types.ObjectId, - ref: 'Event', - }, - ], - adminFor: [ - { - type: Schema.Types.ObjectId, - ref: 'Organization', - }, - ], - membershipRequests: [ - { - type: Schema.Types.ObjectId, - ref: 'MembershipRequest', - }, - ], - organizationsBlockedBy: [ - { - type: Schema.Types.ObjectId, - ref: 'Organization', - }, - ], - status: { - type: String, - required: true, - default: 'ACTIVE', - enum: ['ACTIVE', 'BLOCKED', 'DELETED'], - }, - organizationUserBelongsTo: { - type: Schema.Types.ObjectId, - ref: 'Organization', - }, - pluginCreationAllowed: { - type: Boolean, - required: true, - default: true, - }, - adminApproved: { - type: Boolean, - default: false, - }, - createdAt: { - type: Date, - default: Date.now, - }, -}); - -userSchema.plugin(mongoosePaginate); -module.exports = mongoose.model('User', userSchema); diff --git a/lib/models/UserAttendes.js b/lib/models/UserAttendes.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lib/resolvers/DirectChat.js b/lib/resolvers/DirectChat.js deleted file mode 100644 index 08cbfc0bd7..0000000000 --- a/lib/resolvers/DirectChat.js +++ /dev/null @@ -1,21 +0,0 @@ -const User = require('../models/User'); -const DirectChatMessage = require('../models/DirectChatMessage'); -const Organization = require('../models/Organization'); - -module.exports = { - users: async (parent) => - await User.find({ - _id: { - $in: [...parent.users], - }, - }), - creator: async (parent) => await User.findById(parent.creator), - messages: async (parent) => - DirectChatMessage.find({ - _id: { - $in: [...parent.messages], - }, - }), - organization: async (parent) => - await Organization.findById(parent.organization), -}; diff --git a/lib/resolvers/DirectChatMessage.js b/lib/resolvers/DirectChatMessage.js deleted file mode 100644 index 439b979b00..0000000000 --- a/lib/resolvers/DirectChatMessage.js +++ /dev/null @@ -1,14 +0,0 @@ -const User = require('../models/User'); -const DirectChat = require('../models/DirectChat'); - -module.exports = { - directChatMessageBelongsTo: async (parent) => { - return await DirectChat.findById(parent.directChatMessageBelongsTo); - }, - sender: async (parent) => { - return await User.findById(parent.sender); - }, - receiver: async (parent) => { - return await User.findById(parent.receiver); - }, -}; diff --git a/lib/resolvers/GroupChat.js b/lib/resolvers/GroupChat.js deleted file mode 100644 index 094970f1fd..0000000000 --- a/lib/resolvers/GroupChat.js +++ /dev/null @@ -1,21 +0,0 @@ -const User = require('../models/User'); -const GroupChatMessage = require('../models/GroupChatMessage'); -const Organization = require('../models/Organization'); - -module.exports = { - users: async (parent) => - await User.find({ - _id: { - $in: [...parent.users], - }, - }), - creator: async (parent) => await User.findById(parent.creator), - messages: async (parent) => - GroupChatMessage.find({ - _id: { - $in: [...parent.messages], - }, - }), - organization: async (parent) => - await Organization.findById(parent.organization), -}; diff --git a/lib/resolvers/GroupChatMessage.js b/lib/resolvers/GroupChatMessage.js deleted file mode 100644 index baed6b4baa..0000000000 --- a/lib/resolvers/GroupChatMessage.js +++ /dev/null @@ -1,11 +0,0 @@ -const User = require('../models/User'); -const GroupChat = require('../models/GroupChat'); - -module.exports = { - groupChatMessageBelongsTo: async (parent) => { - return await GroupChat.findById(parent.groupChatMessageBelongsTo); - }, - sender: async (parent) => { - return await User.findById(parent.sender); - }, -}; diff --git a/lib/resolvers/MembershipRequest.js b/lib/resolvers/MembershipRequest.js deleted file mode 100644 index 3dc9779f78..0000000000 --- a/lib/resolvers/MembershipRequest.js +++ /dev/null @@ -1,8 +0,0 @@ -const User = require('../models/User'); -const Organization = require('../models/Organization'); - -module.exports = { - organization: async (parent) => - await Organization.findOne({ _id: parent.organization }), - user: async (parent) => await User.findOne({ _id: parent.user }), -}; diff --git a/lib/resolvers/Mutation.js b/lib/resolvers/Mutation.js deleted file mode 100644 index 65e6b079b0..0000000000 --- a/lib/resolvers/Mutation.js +++ /dev/null @@ -1,163 +0,0 @@ -const signUp = require('./auth_mutations/signup'); -const login = require('./auth_mutations/login'); -const otp = require('./auth_mutations/otp'); -const recaptcha = require('./auth_mutations/recaptcha'); -const forgotPassword = require('./auth_mutations/forgotPassword'); -const saveFcmToken = require('./auth_mutations/saveFcmToken'); -const logout = require('./auth_mutations/logout'); -const refreshToken = require('./auth_mutations/refresh_token'); -const revokeRefreshTokenForUser = require('./auth_mutations/revoke_refresh_token_for_user'); - -const createEvent = require('./event_mutations/createEvent'); -const removeEvent = require('./event_mutations/removeEvent'); -const updateEvent = require('./event_mutations/updateEvent'); -const createOrganization = require('./organization_mutations/createOrganization'); -const updateOrganization = require('./organization_mutations/updateOrganization'); -const removeOrganization = require('./organization_mutations/removeOrganization'); -const createAdmin = require('./admin_mutations/createAdmin'); -const removeAdmin = require('./admin_mutations/removeAdmin'); -const joinPublicOrganization = require('./member_mutations/join_public_organization'); -const leaveOrganization = require('./member_mutations/leave_organization'); -const removeMember = require('./member_mutations/removeMember'); -const updateUserProfile = require('./user_mutations/updateUserProfile'); -const updateUserType = require('./user_mutations/updateUserType'); -const registerForEvent = require('./event_mutations/registerForEvent'); -const unregisterForEventByUser = require('./event_mutations/unregisterForEvent'); -// const createEventProject = require("./event_project_mutations/createProject") -// const removeEventProject = require("./event_project_mutations/removeProject") -// const updateEventProject = require("./event_project_mutations/updateProject") - -const createTask = require('./project_task_mutations/createTask'); -const removeTask = require('./project_task_mutations/removeTask'); -const updateTask = require('./project_task_mutations/updateTask'); -const adminRemovePost = require('./admin_mutations/admin-remove-post'); -const adminRemoveEvent = require('./admin_mutations/admin-remove-event'); -const adminRemoveGroup = require('./admin_mutations/admin-remove-group-chat'); - -const { acceptAdmin, rejectAdmin } = require('./admin_mutations/adminRequest'); - -const createPost = require('./post_mutations/createPost'); -const removePost = require('./post_mutations/removePost'); -const createComment = require('./post_mutations/createComment'); -const removeComment = require('./post_mutations/removeComment'); -const likeComment = require('./post_mutations/likeComment'); -const unlikeComment = require('./post_mutations/unlikeComment'); -const likePost = require('./post_mutations/likePost'); -const unlikePost = require('./post_mutations/unlikePost'); - -const sendMembershipRequest = require('./membership_request_mutations/send_membership_request'); -const acceptMembershipRequest = require('./membership_request_mutations/accept_membership_request'); -const rejectMembershipRequest = require('./membership_request_mutations/reject_membership_request'); -const cancelMembershipRequest = require('./membership_request_mutations/cancel_membership_request'); - -const blockUser = require('./block_user_mutations/block_user'); -const unblockUser = require('./block_user_mutations/unblock_user'); - -const addUserImage = require('./user_image_mutations/add_user_image'); -const removeUserImage = require('./user_image_mutations/remove_user_image'); -const addOrganizationImage = require('./organization_image_mutations/add_organization_image'); -const removeOrganizationImage = require('./organization_image_mutations/remove_organization_image'); - -const createDirectChat = require('./direct_chat_mutations/createDirectChat'); -const removeDirectChat = require('./direct_chat_mutations/removeDirectChat'); -const sendMessageToDirectChat = require('./direct_chat_mutations/sendMessageToDirectChat'); -const createGroupChat = require('./group_chat_mutations/createGroupChat'); -const removeGroupChat = require('./group_chat_mutations/removeGroupChat'); -const sendMessageToGroupChat = require('./group_chat_mutations/sendMessageToGroupChat'); -const addUserToGroupChat = require('./group_chat_mutations/addUserToGroupChat'); -const removeUserFromGroupChat = require('./group_chat_mutations/removeUserFromGroupChat'); -const updateLanguage = require('./language_mutation/updateLanguage'); -const blockPluginCreationBySuperadmin = require('../resolvers/user_mutations/blockForPlugin'); - -const createMessageChat = require('./message_chat_mutation/createMessageChat'); -const addLanguageTranslation = require('./language_maintainer_mutation/addLanguageTranslation'); - -const createPlugin = require('./plugin_mutations/createPlugin'); -const updatePluginStatus = require('./plugin_mutations/updatePluginStatus'); -const updatePluginInstalledOrgs = require('./plugin_mutations/updatePluginInstalledOrgs'); - -const Mutation = { - signUp, - login, - otp, - recaptcha, - forgotPassword, - saveFcmToken, - logout, - refreshToken, - revokeRefreshTokenForUser, - updateLanguage, - - updateUserProfile, - updateUserType, - createOrganization, - - createEvent, - registerForEvent, - removeEvent, - updateEvent, - unregisterForEventByUser, - - acceptAdmin, - rejectAdmin, - - createAdmin, - removeAdmin, - updateOrganization, - removeOrganization, - joinPublicOrganization, - leaveOrganization, - removeMember, - //removeMultipleMembers, - - adminRemovePost, - adminRemoveGroup, - adminRemoveEvent, - // createEventProject, - // removeEventProject, - // updateEventProject, - createPost, - removePost, - likePost, - unlikePost, - createTask, - removeTask, - updateTask, - sendMembershipRequest, - acceptMembershipRequest, - rejectMembershipRequest, - cancelMembershipRequest, - - blockUser, - unblockUser, - - createComment, - removeComment, - likeComment, - unlikeComment, - - addUserImage, - removeUserImage, - addOrganizationImage, - removeOrganizationImage, - - createDirectChat, - removeDirectChat, - sendMessageToDirectChat, - - createGroupChat, - removeGroupChat, - sendMessageToGroupChat, - addUserToGroupChat, - removeUserFromGroupChat, - blockPluginCreationBySuperadmin, - - createMessageChat, - addLanguageTranslation, - - createPlugin, - updatePluginStatus, - updatePluginInstalledOrgs, -}; - -module.exports = Mutation; diff --git a/lib/resolvers/Organization.js b/lib/resolvers/Organization.js deleted file mode 100644 index 79b90b9e57..0000000000 --- a/lib/resolvers/Organization.js +++ /dev/null @@ -1,52 +0,0 @@ -const User = require('../models/User'); -const MembershipRequest = require('../models/MembershipRequest'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const Organization = { - creator: async (parent) => { - const user = await User.findById(parent.creator._id); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - return user; - }, - admins: async (parent) => { - const admins = await User.find({ - _id: { - $in: [...parent.admins], - }, - }); - return admins; - }, - members: async (parent) => { - const members = await User.find({ - _id: { - $in: [...parent.members], - }, - }); - return members; - }, - membershipRequests: async (parent) => { - const membershipRequests = await MembershipRequest.find({ - _id: { - $in: [...parent.membershipRequests], - }, - }); - return membershipRequests; - }, - blockedUsers: async (parent) => { - const users = await User.find({ - _id: { - $in: [...parent.blockedUsers], - }, - }); - return users; - }, -}; - -module.exports = Organization; diff --git a/lib/resolvers/Query.js b/lib/resolvers/Query.js deleted file mode 100644 index 9712cafae1..0000000000 --- a/lib/resolvers/Query.js +++ /dev/null @@ -1,75 +0,0 @@ -const groupChats = require('./group_chat_query/groupChats'); -const groupChatMessages = require('./group_chat_query/groupChatMessages'); -const directChats = require('./direct_chat_query/directChats'); -const directChatMessages = require('./direct_chat_query/directChatMessages'); -const organizations = require('./organization_query/organizations'); -const event = require('./event_query/event'); -const registrantsByEvent = require('./event_query/registrantsByEvent'); -const events = require('./event_query/events'); -const isUserRegister = require('./event_query/isUserRegister'); -const eventsByOrganization = require('./event_query/eventsByOrganization'); -const registeredEventsByUser = require('./event_query/registeredEventsByUser'); -const tasksByEvent = require('./event_query/tasksByEvent'); -const tasksByUser = require('./user_query/tasksByUser'); -const comments = require('./post_query/comments'); -const commentsByPost = require('./post_query/commentsByPost'); -const post = require('./post_query/post'); -const posts = require('./post_query/posts'); -const postsByOrganization = require('./post_query/postsByOrganization'); -const groups = require('./group_query/groups'); -const organizationsConnection = require('./organization_query/organizations_pagination'); -const postsByOrganizationConnection = require('../resolvers/post_organization_query/organization_post_pagination'); -const { users, user, me } = require('./user_query/users'); -const { usersConnection } = require('./user_query/users'); -const { organizationsMemberConnection } = require('./user_query/users'); -const myLanguage = require('../resolvers/user_query/myLanguage'); -const userLanguage = require('../resolvers/user_query/userLanguage'); -const getlanguage = require('../resolvers/language_maintainer_query/getlanguage'); -const directChatsByUserID = require('./direct_chat_query/directChatsByUserID'); -const directChatsMessagesByChatID = require('./direct_chat_query/directChatsMessagesByChatID'); -const checkAuth = require('./auth_query/checkAuth'); -const getPlugins = require('./plugin_query/getPlugins'); -const Query = { - me, - user, - users, - usersConnection, - - checkAuth, - - organizations, - organizationsConnection, - organizationsMemberConnection, - - isUserRegister, - event, - events, - registrantsByEvent, - eventsByOrganization, - registeredEventsByUser, - - groupChats, - groupChatMessages, - directChats, - directChatMessages, - directChatsByUserID, - directChatsMessagesByChatID, - - tasksByEvent, - tasksByUser, - comments, - commentsByPost, - post, - posts, - postsByOrganization, - postsByOrganizationConnection, - groups, - - myLanguage, - userLanguage, - - getlanguage, - getPlugins, -}; - -module.exports = Query; diff --git a/lib/resolvers/Subscription.js b/lib/resolvers/Subscription.js deleted file mode 100644 index 832c01919e..0000000000 --- a/lib/resolvers/Subscription.js +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable eqeqeq */ -const { withFilter } = require('apollo-server-express'); -const MESSAGE_SENT_TO_DIRECT_CHAT = 'MESSAGE_SENT_TO_DIRECT_CHAT'; -const MESSAGE_SENT_TO_GROUP_CHAT = 'MESSAGE_SENT_TO_GROUP_CHAT'; -const CHAT_CHANNEL = 'CHAT_CHANNEL'; -const GroupChat = require('../models/GroupChat'); - -const Subscription = { - messageSentToDirectChat: { - subscribe: withFilter( - (parent, args, { pubsub }) => - pubsub.asyncIterator([MESSAGE_SENT_TO_DIRECT_CHAT]), - (payload, variables, context) => { - const { currentUserId } = context.context; - return ( - currentUserId == payload.messageSentToDirectChat.receiver || - currentUserId == payload.messageSentToDirectChat.sender - ); - } - ), - }, - messageSentToGroupChat: { - // Show All messages sent to group chats the user belongs to but he didnt send ie the current user did not send the message - subscribe: withFilter( - (parent, args, context) => - context.pubsub.asyncIterator([MESSAGE_SENT_TO_GROUP_CHAT]), - async (payload, variables, context) => { - const { currentUserId } = context.context; - const groupChatId = - payload.messageSentToGroupChat.groupChatMessageBelongsTo; - - const groupChat = await GroupChat.findById(groupChatId); - const userIsInGroupChat = groupChat.users.includes(currentUserId); - return userIsInGroupChat; - } - ), - }, - directMessageChat: { - subscribe: withFilter( - (parent, args, context) => context.pubsub.asyncIterator(CHAT_CHANNEL), - (payload) => { - const chat = payload.directMessageChat; - console.log(chat); - return chat; - } - ), - }, -}; - -module.exports = Subscription; diff --git a/lib/resolvers/admin_mutations/admin-remove-event.js b/lib/resolvers/admin_mutations/admin-remove-event.js deleted file mode 100644 index 433bd046aa..0000000000 --- a/lib/resolvers/admin_mutations/admin-remove-event.js +++ /dev/null @@ -1,71 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const Event = require('../../models/Event'); -const adminCheck = require('../functions/adminCheck'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - //find event - let event = await Event.findOne({ _id: args.eventId }); - if (!event) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Event not found' - : requestContext.translate('event.notFound'), - 'event.notFound', - 'event' - ); - } - - //ensure organization exists - let org = await Organization.findOne({ _id: event.organization }); - if (!org) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Organization not found' - : requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - //gets user in token - to be used later on - let user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'User not found' - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - //ensure user is an admin - adminCheck(context, org); - - //remove event from user - user.overwrite({ - ...user._doc, - eventAdmin: user._doc.eventAdmin.filter( - (eventAdmin) => eventAdmin !== event.id - ), - createdEvents: user._doc.createdEvents.filter( - (createdEvent) => createdEvent !== event.id - ), - registeredEvents: user._doc.registeredEvents.filter( - (registeredEvent) => registeredEvent !== event.id - ), - }); - - await user.save(); - - //delete post - await Event.deleteOne({ _id: args.eventId }); - - //return user - return { - ...event._doc, - }; -}; diff --git a/lib/resolvers/admin_mutations/admin-remove-group-chat.js b/lib/resolvers/admin_mutations/admin-remove-group-chat.js deleted file mode 100644 index b1386df8e4..0000000000 --- a/lib/resolvers/admin_mutations/admin-remove-group-chat.js +++ /dev/null @@ -1,86 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const adminCheck = require('../functions/adminCheck'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const GroupChat = require('../../models/GroupChat'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, - CHAT_NOT_FOUND, - CHAT_NOT_FOUND_PARAM, - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_MESSAGE, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - //find message - let group = await GroupChat.findOne({ _id: args.groupId }); - - if (!group) { - throw new NotFoundError( - !IN_PRODUCTION - ? CHAT_NOT_FOUND - : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM - ); - } - - //ensure organization exists - let org = await Organization.findOne({ _id: group._doc.organization._id }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - //gets user in token - to be used later on - let user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - //ensure user is an admin - adminCheck(context, org); - - //remove message from organization - // org.overwrite({ - // ...org._doc, - // messages: org._doc.posts.filter((message) => message != args.messageId), - // }); - // await org.save(); - - // //remove post from user - // user.overwrite({ - // ...user._doc, - // messages: user._doc.posts.filter((message) => message != args.messageId), - // }); - // await user.save(); - - //delete post - await GroupChat.deleteOne({ _id: args.groupId }); - - //return user - return { - ...group._doc, - }; -}; diff --git a/lib/resolvers/admin_mutations/admin-remove-post.js b/lib/resolvers/admin_mutations/admin-remove-post.js deleted file mode 100644 index 8ce1a3c8e4..0000000000 --- a/lib/resolvers/admin_mutations/admin-remove-post.js +++ /dev/null @@ -1,67 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const Post = require('../../models/Post'); -const adminCheck = require('../functions/adminCheck'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - //ensure organization exists - let org = await Organization.findOne({ _id: args.organizationId }); - if (!org) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Organization not found' - : requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - //gets user in token - to be used later on - let user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'User not found' - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - //ensure user is an admin - adminCheck(context, org); - - //find post - let post = await Post.findOne({ _id: args.postId }); - if (!post) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Post not found' - : requestContext.translate('post.notFound'), - 'post.notFound', - 'post' - ); - } - - //remove post from organization - org.overwrite({ - ...org._doc, - posts: org._doc.posts.filter((post) => post !== args.postId), - }); - await org.save(); - - // //remove post from user - // user.overwrite({ - // ...user._doc, - // posts: user._doc.posts.filter((post) => post != args.postId), - // }); - // await user.save(); - - //delete post - await Post.deleteOne({ _id: args.postId }); - - //return user - return post._doc; -}; diff --git a/lib/resolvers/admin_mutations/adminRequest.js b/lib/resolvers/admin_mutations/adminRequest.js deleted file mode 100644 index 4eddd4d7f4..0000000000 --- a/lib/resolvers/admin_mutations/adminRequest.js +++ /dev/null @@ -1,37 +0,0 @@ -const { USER_NOT_AUTHORIZED } = require('../../../constants'); -const userExists = require('../../helper_functions/userExists'); -const User = require('../../models/User'); - -const acceptAdmin = async (parent, args, context) => { - const { id } = args; - - const isSuperAdmin = await userExists(context.userId); - - if (isSuperAdmin.userType !== 'SUPERADMIN') { - throw new Error(USER_NOT_AUTHORIZED); - } - - await userExists(id); - - await User.findByIdAndUpdate({ _id: id }, { adminApproved: true }); - - return true; -}; - -const rejectAdmin = async (parent, args, context) => { - const { id } = args; - - const isSuperAdmin = await userExists(context.userId); - - if (isSuperAdmin.userType !== 'SUPERADMIN') { - throw new Error(USER_NOT_AUTHORIZED); - } - - await userExists(id); - - await User.findByIdAndDelete({ _id: id }); - - return true; -}; - -module.exports = { acceptAdmin, rejectAdmin }; diff --git a/lib/resolvers/admin_mutations/createAdmin.js b/lib/resolvers/admin_mutations/createAdmin.js deleted file mode 100644 index 4bcb73efb9..0000000000 --- a/lib/resolvers/admin_mutations/createAdmin.js +++ /dev/null @@ -1,98 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const creatorCheck = require('../functions/creatorCheck'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, - ORGANIZATION_MEMBER_NOT_FOUND, - ORGANIZATION_MEMBER_NOT_FOUND_MESSAGE, - ORGANIZATION_MEMBER_NOT_FOUND_CODE, - ORGANIZATION_MEMBER_NOT_FOUND_PARAM, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - // checks to see if organization exists - const org = await Organization.findOne({ _id: args.data.organizationId }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - // check if the user adding the admin is the creator of the organization - creatorCheck(context, org); - - // ensures user to be made admin exists - const user = await User.findOne({ _id: args.data.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - // ensures user is a member of the organization - const member = org._doc.members.filter( - (member) => member.toString() === user.id - ); - if (member.length === 0) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_MEMBER_NOT_FOUND - : requestContext.translate(ORGANIZATION_MEMBER_NOT_FOUND_MESSAGE), - ORGANIZATION_MEMBER_NOT_FOUND_CODE, - ORGANIZATION_MEMBER_NOT_FOUND_PARAM - ); - } - - // checks if user is already admin of the organization - const admin = org._doc.admins.filter((admin) => admin.toString() === user.id); - if (admin.length === 1) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - // ADDS ADMIN TO ORGANIZATION - org.overwrite({ - ...org._doc, - admins: [...org._doc.admins, user], - }); - await org.save(); - - // Adds organization to the user's admin for field - user.overwrite({ - ...user._doc, - adminFor: [...user._doc.adminFor, org], - }); - await user.save(); - - return { - ...user.toObject(), - password: null, - }; -}; diff --git a/lib/resolvers/admin_mutations/removeAdmin.js b/lib/resolvers/admin_mutations/removeAdmin.js deleted file mode 100644 index fa1884a8ab..0000000000 --- a/lib/resolvers/admin_mutations/removeAdmin.js +++ /dev/null @@ -1,83 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const creatorCheck = require('../functions/creatorCheck'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_PARAM, - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_PARAM, - USER_NOT_FOUND_CODE, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - // ensure organization exists - const org = await Organization.findOne({ _id: args.data.organizationId }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - // ensure user exists - const user = await User.findOne({ _id: args.data.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - // ensure user is an admin - const admin = org._doc.admins.filter((admin) => admin.toString() === user.id); - if (admin.length === 0) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - // ensure user trying to remove admin is the creator - creatorCheck(context, org); - - // remove admin from organization - org.overwrite({ - ...org._doc, - admins: org._doc.admins.filter((admin) => admin.toString() !== user.id), - }); - await org.save(); - - // remove organization from the user's adminFor field - user.overwrite({ - ...user._doc, - adminFor: user._doc.adminFor.filter( - (organization) => organization.toString() !== org.id - ), - }); - await user.save(); - - // return user - return { - ...user.toObject(), - password: null, - }; -}; diff --git a/lib/resolvers/auth_mutations/forgotPassword.js b/lib/resolvers/auth_mutations/forgotPassword.js deleted file mode 100644 index 2da3aabd8f..0000000000 --- a/lib/resolvers/auth_mutations/forgotPassword.js +++ /dev/null @@ -1,31 +0,0 @@ -const bcrypt = require('bcryptjs'); -const jwt_decode = require('jwt-decode'); - -const { INVALID_OTP } = require('../../../constants'); - -const User = require('../../models/User'); - -module.exports = async (parent, args) => { - const { userOtp, newPassword, otpToken } = args.data; - - const { email, otp } = jwt_decode(otpToken); - - const isOtpValid = await bcrypt.compare(userOtp, otp); - - if (!isOtpValid) { - throw new Error(INVALID_OTP); - } - - const hashedPassword = await bcrypt.hash(newPassword, 12); - - const isChanges = await User.findOneAndUpdate( - { email }, - { password: hashedPassword } - ); - - if (isChanges) { - return true; - } - - return false; -}; diff --git a/lib/resolvers/auth_mutations/login.js b/lib/resolvers/auth_mutations/login.js deleted file mode 100644 index c220a7678d..0000000000 --- a/lib/resolvers/auth_mutations/login.js +++ /dev/null @@ -1,67 +0,0 @@ -const bcrypt = require('bcryptjs'); -const User = require('../../models/User'); -const { - createAccessToken, - createRefreshToken, -} = require('../../helper_functions/auth'); -const { NotFoundError, ValidationError } = require('errors'); -const requestContext = require('talawa-request-context'); -const copyToClipboard = require('../functions/copyToClipboard'); -const { - androidFirebaseOptions, - iosFirebaseOptions, -} = require('../../../firebaseOptions'); - -module.exports = async (parent, args) => { - const user = await User.findOne({ email: args.data.email.toLowerCase() }) - .populate('joinedOrganizations') - .populate('createdOrganizations') - .populate('createdEvents') - .populate('registeredEvents') - .populate('eventAdmin') - .populate('adminFor') - .populate('membershipRequests') - .populate('organizationsBlockedBy') - .populate('organizationUserBelongsTo'); - - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const isEqual = await bcrypt.compare(args.data.password, user._doc.password); - - if (!isEqual) { - throw new ValidationError( - [ - { - message: requestContext.translate('invalid.credentials'), - code: 'invalid.credentials', - param: 'credentials', - }, - ], - requestContext.translate('invalid.credentials') - ); - } - - const accessToken = await createAccessToken(user); - const refreshToken = await createRefreshToken(user); - - copyToClipboard(`{ - "Authorization": "Bearer ${accessToken}" -}`); - - return { - user: { - ...user._doc, - password: null, - }, - accessToken, - refreshToken, - androidFirebaseOptions, - iosFirebaseOptions, - }; -}; diff --git a/lib/resolvers/auth_mutations/logout.js b/lib/resolvers/auth_mutations/logout.js deleted file mode 100644 index 217fde2210..0000000000 --- a/lib/resolvers/auth_mutations/logout.js +++ /dev/null @@ -1,29 +0,0 @@ -const User = require('../../models/User'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - USER_NOT_FOUND, - IN_PRODUCTION, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - user.token = null; - - await user.save(); - - return true; -}; diff --git a/lib/resolvers/auth_mutations/otp.js b/lib/resolvers/auth_mutations/otp.js deleted file mode 100644 index 618448af79..0000000000 --- a/lib/resolvers/auth_mutations/otp.js +++ /dev/null @@ -1,38 +0,0 @@ -const bcrypt = require('bcryptjs'); -const jwt = require('jsonwebtoken'); - -const User = require('../../models/User'); -const mailer = require('../../helper_functions/mailer'); -const { USER_NOT_FOUND } = require('../../../constants'); - -module.exports = async (parent, args) => { - const { email } = args.data; - - const user = await User.findOne({ email }); - - if (!user) { - throw new Error(USER_NOT_FOUND); - } - - const username = `${user.firstName} ${user.lastName}`; - - const otp = (Math.floor(Math.random() * 10000) + 9999).toString(); - - const hashedOtp = await bcrypt.hash(otp, 10); - - const otpToken = jwt.sign( - { email, otp: hashedOtp }, - process.env.ACCESS_TOKEN_SECRET, - { - expiresIn: '15m', - } - ); - - const subject = 'OTP for Talawa-admin forgot password'; - const body = `

Hi, ${username}

Your OTP: ${otp}

Your OTP will expires in 5 minutes.



Do not share your otp with others.`; - - return mailer(email, subject, body).then((info) => { - console.log(info); - return { otpToken }; - }); -}; diff --git a/lib/resolvers/auth_mutations/recaptcha.js b/lib/resolvers/auth_mutations/recaptcha.js deleted file mode 100644 index 8451d6548d..0000000000 --- a/lib/resolvers/auth_mutations/recaptcha.js +++ /dev/null @@ -1,11 +0,0 @@ -const axios = require('axios'); - -module.exports = async (parent, args) => { - const { recaptchaToken } = args.data; - - const response = await axios.post( - `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${recaptchaToken}` - ); - - return response.data.success; -}; diff --git a/lib/resolvers/auth_mutations/refresh_token.js b/lib/resolvers/auth_mutations/refresh_token.js deleted file mode 100644 index c13a350555..0000000000 --- a/lib/resolvers/auth_mutations/refresh_token.js +++ /dev/null @@ -1,61 +0,0 @@ -const jwt = require('jsonwebtoken'); -const User = require('../../models/User'); -const { - createAccessToken, - createRefreshToken, -} = require('../../helper_functions/auth'); -const { ValidationError, NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args) => { - // This route should not be protected because the access token will be expired - const refreshToken = args.refreshToken; - if (!refreshToken) { - throw new ValidationError( - [ - { - message: requestContext.translate('invalid.refreshToken'), - code: 'invalid.refreshToken', - param: 'refreshToken', - }, - ], - requestContext.translate('invalid.refreshToken') - ); - } - - let payload = null; - - payload = jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET); - - // The refresh token received is valid so we cna send a new access token - const user = await User.findOne({ _id: payload.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - if (user.tokenVersion !== payload.tokenVersion) { - throw new ValidationError( - [ - { - message: requestContext.translate('invalid.refreshToken'), - code: 'invalid.refreshToken', - param: 'refreshToken', - }, - ], - requestContext.translate('invalid.refreshToken') - ); - } - - // send new access and refresh token to user - const newAccessToken = await createAccessToken(user); - const newRefreshToken = await createRefreshToken(user); - - return { - accessToken: newAccessToken, - refreshToken: newRefreshToken, - }; -}; diff --git a/lib/resolvers/auth_mutations/revoke_refresh_token_for_user.js b/lib/resolvers/auth_mutations/revoke_refresh_token_for_user.js deleted file mode 100644 index 9d09126b12..0000000000 --- a/lib/resolvers/auth_mutations/revoke_refresh_token_for_user.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable indent */ -const User = require('../../models/User'); - -module.exports = async (parent, args) => { - await User.findOneAndUpdate( - { _id: args.userId }, - { - $inc: { - tokenVersion: 1, - }, - }, - { - new: true, - } - ); - return true; -}; diff --git a/lib/resolvers/auth_mutations/saveFcmToken.js b/lib/resolvers/auth_mutations/saveFcmToken.js deleted file mode 100644 index b1a04cf451..0000000000 --- a/lib/resolvers/auth_mutations/saveFcmToken.js +++ /dev/null @@ -1,29 +0,0 @@ -const User = require('../../models/User'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - USER_NOT_FOUND, - IN_PRODUCTION, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - const user = await User.findById(context.userId); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - user.token = args.token; - - await user.save(); - - return true; -}; diff --git a/lib/resolvers/auth_mutations/signup.js b/lib/resolvers/auth_mutations/signup.js deleted file mode 100644 index 1abb7cd1ec..0000000000 --- a/lib/resolvers/auth_mutations/signup.js +++ /dev/null @@ -1,78 +0,0 @@ -const Organization = require('../../models/Organization'); -const { NotFoundError, ConflictError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const User = require('../../models/User'); -const bcrypt = require('bcryptjs'); -const { - createAccessToken, - createRefreshToken, -} = require('../../helper_functions/auth'); - -const uploadImage = require('../../helper_functions/uploadImage'); -const copyToClipboard = require('../functions/copyToClipboard.js'); - -module.exports = async (parent, args) => { - const emailTaken = await User.findOne({ - email: args.data.email.toLowerCase(), - }); - if (emailTaken) { - throw new ConflictError( - requestContext.translate('email.alreadyExists'), - 'email.alreadyExists', - 'email' - ); - } - - // TODO: this check is to be removed - let org; - if (args.data.organizationUserBelongsToId) { - org = await Organization.findOne({ - _id: args.data.organizationUserBelongsToId, - }); - if (!org) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - } - - const hashedPassword = await bcrypt.hash(args.data.password, 12); - - // Upload file - let uploadImageObj; - if (args.file) { - uploadImageObj = await uploadImage(args.file, null); - } - - let user = new User({ - ...args.data, - organizationUserBelongsTo: org ? org : null, - email: args.data.email.toLowerCase(), // ensure all emails are stored as lowercase to prevent duplicated due to comparison errors - image: uploadImageObj - ? uploadImageObj.imageAlreadyInDbPath - ? uploadImageObj.imageAlreadyInDbPath - : uploadImageObj.newImagePath - : null, - password: hashedPassword, - }); - - user = await user.save(); - const accessToken = await createAccessToken(user); - const refreshToken = await createRefreshToken(user); - - copyToClipboard(`{ - "Authorization": "Bearer ${accessToken}" -}`); - - return { - user: { - ...user._doc, - password: null, - }, - accessToken, - refreshToken, - }; -}; diff --git a/lib/resolvers/auth_query/checkAuth.js b/lib/resolvers/auth_query/checkAuth.js deleted file mode 100644 index f1354c08d4..0000000000 --- a/lib/resolvers/auth_query/checkAuth.js +++ /dev/null @@ -1,12 +0,0 @@ -const userExists = require('../../helper_functions/userExists'); -const { USER_NOT_FOUND } = require('../../../constants'); - -module.exports = async (parent, args, context) => { - let userFound = await userExists(context.userId); - if (!userFound) throw new Error(USER_NOT_FOUND); - - return { - ...userFound?._doc, - organizationsBlockedBy: [], - }; -}; diff --git a/lib/resolvers/block_user_mutations/block_user.js b/lib/resolvers/block_user_mutations/block_user.js deleted file mode 100644 index adbf2a9746..0000000000 --- a/lib/resolvers/block_user_mutations/block_user.js +++ /dev/null @@ -1,55 +0,0 @@ -const adminCheck = require('../functions/adminCheck'); -const organizationExists = require('../../helper_functions/organizationExists'); -const userExists = require('../../helper_functions/userExists'); -const { UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - // ensure org exists - const org = await organizationExists(args.organizationId); - // ensure user exists - const user = await userExists(args.userId); - - // ensure user is admin - adminCheck(context, org); - // ensure user isnt already blocked - const blocked = org._doc.blockedUsers.filter( - (blockedUser) => blockedUser.toString() === user.id - ); - - if (blocked[0]) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - // add user to organizations blocked users field - org.overwrite({ - ...org._doc, - blockedUsers: [...org._doc.blockedUsers, user], - }); - await org.save(); - - // add organization to users organizationsblockedbyfield - user.overwrite({ - ...user._doc, - organizationsBlockedBy: [...user._doc.organizationsBlockedBy, org._id], - }); - await user.save(); - - return { - ...user._doc, - password: null, - }; -}; diff --git a/lib/resolvers/block_user_mutations/unblock_user.js b/lib/resolvers/block_user_mutations/unblock_user.js deleted file mode 100644 index 08146e3ecc..0000000000 --- a/lib/resolvers/block_user_mutations/unblock_user.js +++ /dev/null @@ -1,60 +0,0 @@ -const adminCheck = require('../functions/adminCheck'); -const organizationExists = require('../../helper_functions/organizationExists'); -const userExists = require('../../helper_functions/userExists'); -const { UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - // ensure org exists - const org = await organizationExists(args.organizationId); - - // ensure user exists - const user = await userExists(args.userId); - - // ensure user is admin - adminCheck(context, org); - - // ensure user is blocked - const blocked = org._doc.blockedUsers.filter( - (blockedUser) => blockedUser.toString() === user.id - ); - if (!blocked[0]) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - // remove user from the blockedUsers array inside the organization record. - org.overwrite({ - ...org._doc, - blockedUsers: org._doc.blockedUsers.filter( - (blockedUser) => blockedUser.toString() !== user.id - ), - }); - await org.save(); - - // remove the organization from the organizationsBlockedBy array inside the user record. - user.overwrite({ - ...user._doc, - organizationsBlockedBy: user._doc.organizationsBlockedBy.filter( - (organization) => organization.toString() !== org.id - ), - }); - await user.save(); - - return { - ...user._doc, - password: null, - }; -}; diff --git a/lib/resolvers/direct_chat_mutations/createDirectChat.js b/lib/resolvers/direct_chat_mutations/createDirectChat.js deleted file mode 100644 index 74ce73e41f..0000000000 --- a/lib/resolvers/direct_chat_mutations/createDirectChat.js +++ /dev/null @@ -1,56 +0,0 @@ -const User = require('../../models/User'); -const DirectChat = require('../../models/DirectChat'); -const Organization = require('../../models/Organization'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - let user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'User not found' - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const org = await Organization.findOne({ _id: args.data.organizationId }); - if (!org) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Organization not Found' - : requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - const usersInChat = []; - - // add users to cat - for await (const userId of args.data.userIds) { - const user = await await User.findOne({ _id: userId }); - if (!user) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'User not found' - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - usersInChat.push(user); - } - - let directChat = new DirectChat({ - creator: user, - users: usersInChat, - organization: org, - }); - - directChat = await directChat.save(); - - return directChat.toObject(); -}; diff --git a/lib/resolvers/direct_chat_mutations/removeDirectChat.js b/lib/resolvers/direct_chat_mutations/removeDirectChat.js deleted file mode 100644 index 45703a8a9e..0000000000 --- a/lib/resolvers/direct_chat_mutations/removeDirectChat.js +++ /dev/null @@ -1,34 +0,0 @@ -const DirectChat = require('../../models/DirectChat'); -const DirectChatMessage = require('../../models/DirectChatMessage'); -const adminCheck = require('../functions/adminCheck'); -const organizationExists = require('../../helper_functions/organizationExists'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -// admins of the organization can remove chats -- may change in the future - -module.exports = async (parent, args, context) => { - const org = await organizationExists(args.organizationId); - - const chat = await DirectChat.findById(args.chatId); - if (!chat) { - throw new NotFoundError( - requestContext.translate('chat.notFound'), - 'chat.notFound', - 'chat' - ); - } - - adminCheck(context, org); - - // delete all messages in the chat - await DirectChatMessage.deleteMany({ - _id: { - $in: [...chat.messages], - }, - }); - - await DirectChat.deleteOne({ _id: args.chatId }); - - return chat; -}; diff --git a/lib/resolvers/direct_chat_mutations/sendMessageToDirectChat.js b/lib/resolvers/direct_chat_mutations/sendMessageToDirectChat.js deleted file mode 100644 index c5cfef4bb8..0000000000 --- a/lib/resolvers/direct_chat_mutations/sendMessageToDirectChat.js +++ /dev/null @@ -1,57 +0,0 @@ -const DirectChat = require('../../models/DirectChat'); -const DirectChatMessage = require('../../models/DirectChatMessage'); -const userExists = require('../../helper_functions/userExists'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - CHAT_NOT_FOUND, - CHAT_NOT_FOUND_MESSAGE, - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM, -} = require('../../../constants'); -module.exports = async (parent, args, context) => { - const chat = await DirectChat.findById(args.chatId); - if (!chat) { - throw new NotFoundError( - !IN_PRODUCTION - ? CHAT_NOT_FOUND - : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM - ); - } - - const sender = await userExists(context.userId); - - const receiver = chat.users.filter((u) => u.toString() !== sender.id); - - const message = new DirectChatMessage({ - directChatMessageBelongsTo: chat._doc, - sender: sender._id, - receiver: receiver, - createdAt: new Date(), - messageContent: args.messageContent, - }); - - await message.save(); - - // add message to chat - await DirectChat.updateOne( - { - _id: args.chatId, - }, - { - $set: { - messages: [...chat._doc.messages, message], - }, - } - ); - - //calls subscription - context.pubsub.publish('MESSAGE_SENT_TO_DIRECT_CHAT', { - messageSentToDirectChat: message._doc, - }); - - return message._doc; -}; diff --git a/lib/resolvers/direct_chat_query/directChatMessages.js b/lib/resolvers/direct_chat_query/directChatMessages.js deleted file mode 100644 index 71be8477f1..0000000000 --- a/lib/resolvers/direct_chat_query/directChatMessages.js +++ /dev/null @@ -1,5 +0,0 @@ -const DirectChatMessages = require('../../models/DirectChatMessage'); - -module.exports = async () => { - return await DirectChatMessages.find(); -}; diff --git a/lib/resolvers/direct_chat_query/directChats.js b/lib/resolvers/direct_chat_query/directChats.js deleted file mode 100644 index 893eeb4b93..0000000000 --- a/lib/resolvers/direct_chat_query/directChats.js +++ /dev/null @@ -1,5 +0,0 @@ -const DirectChat = require('../../models/DirectChat'); - -module.exports = async () => { - return await DirectChat.find(); -}; diff --git a/lib/resolvers/direct_chat_query/directChatsByUserID.js b/lib/resolvers/direct_chat_query/directChatsByUserID.js deleted file mode 100644 index 283f4aecda..0000000000 --- a/lib/resolvers/direct_chat_query/directChatsByUserID.js +++ /dev/null @@ -1,22 +0,0 @@ -///Resolver to find direct chats by User ID. - -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const DirectChat = require('../../models/DirectChat'); - -module.exports = async (parent, args) => { - const directChatsFound = await DirectChat.find({ users: args.id }); - - if (directChatsFound.length === 0) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'DirectChats not found' - : requestContext.translate('directChats.notFound'), - 'directChats.notFound', - 'directChats' - ); - } - - return directChatsFound; -}; diff --git a/lib/resolvers/direct_chat_query/directChatsMessagesByChatID.js b/lib/resolvers/direct_chat_query/directChatsMessagesByChatID.js deleted file mode 100644 index 993221b285..0000000000 --- a/lib/resolvers/direct_chat_query/directChatsMessagesByChatID.js +++ /dev/null @@ -1,28 +0,0 @@ -///Resolver to find direct chats messages by User ID. - -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const DirectChatMessages = require('../../models/DirectChatMessage'); -const { - IN_PRODUCTION, - CHAT_NOT_FOUND, - CHAT_NOT_FOUND_MESSAGE, - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM, -} = require('../../../constants'); - -module.exports = async (parent, args) => { - const directChatsMessagesFound = await DirectChatMessages.find({ - directChatMessageBelongsTo: args.id, - }); - if (directChatsMessagesFound.length === 0) { - throw new NotFoundError( - !IN_PRODUCTION - ? CHAT_NOT_FOUND - : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM - ); - } - return directChatsMessagesFound; -}; diff --git a/lib/resolvers/event_mutations/createEvent.js b/lib/resolvers/event_mutations/createEvent.js deleted file mode 100644 index 432bc800c8..0000000000 --- a/lib/resolvers/event_mutations/createEvent.js +++ /dev/null @@ -1,129 +0,0 @@ -const { NotFoundError, UnauthorizedError } = require('errors'); -const User = require('../../models/User'); -const Event = require('../../models/Event'); -const Organization = require('../../models/Organization'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, - ORGANIZATION_NOT_AUTHORIZED, - ORGANIZATION_NOT_AUTHORIZED_MESSAGE, - ORGANIZATION_NOT_AUTHORIZED_CODE, - ORGANIZATION_NOT_AUTHORIZED_PARAM, -} = require('../../../constants'); -var admin = require('firebase-admin'); -var { applicationDefault } = require('firebase-admin').credential; - -admin.initializeApp({ credential: applicationDefault() }); - -const createEvent = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - // Ensure Organization Exists - const org = await Organization.findOne({ _id: args.data.organizationId }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - // Check if user created the Organization - let userCreatedOrg = false; - let createdOrganizations = user.createdOrganizations; - - for (let i = 0; i < createdOrganizations.length; i++) { - if (createdOrganizations[i]._id.equals(args.data.organizationId)) { - userCreatedOrg = true; - break; - } - } - - // Check if user joined the Organization - let userJoinedOrg = false; - let joinedOrganizations = user.joinedOrganizations; - - for (let i = 0; i < joinedOrganizations.length; i++) { - if (joinedOrganizations[i]._id.equals(args.data.organizationId)) { - userJoinedOrg = true; - break; - } - } - - // Create Event if User Joined or Created the Organization - if (userCreatedOrg || userJoinedOrg) { - const newEvent = new Event({ - ...args.data, - creator: context.userId, - registrants: [ - { - userId: context.userId, - user: context.userId, - }, - ], - admins: [context.userId], - organization: args.data.organizationId, - }); - await newEvent.save(); - - // add event to the user record - await User.updateOne( - { _id: user.id }, - { - $push: { - eventAdmin: newEvent, - createdEvents: newEvent, - registeredEvents: newEvent, - }, - } - ); - - const members = org.members; - for (let i = 0; i < members.length; i++) { - const member = members[i]; - const memberUser = await User.findOne({ _id: member }); - if (memberUser && memberUser.token) { - await admin.messaging().send({ - token: memberUser.token, - notification: { - title: 'New Event', - body: `${user.firstName} has created a new event in ${org.name}`, - }, - }); - } - } - - return { - ...newEvent._doc, - }; - } - // If user hasen't joined or created the org then throw an error - throw new UnauthorizedError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_AUTHORIZED - : requestContext.translate(ORGANIZATION_NOT_AUTHORIZED_MESSAGE), - ORGANIZATION_NOT_AUTHORIZED_CODE, - ORGANIZATION_NOT_AUTHORIZED_PARAM - ); -}; - -module.exports = createEvent; diff --git a/lib/resolvers/event_mutations/registerForEvent.js b/lib/resolvers/event_mutations/registerForEvent.js deleted file mode 100644 index c622c000f1..0000000000 --- a/lib/resolvers/event_mutations/registerForEvent.js +++ /dev/null @@ -1,124 +0,0 @@ -const User = require('../../models/User'); -const Event = require('../../models/Event'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_MESSAGE, - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM, - REGISTRANT_ALREADY_EXIST, - REGISTRANT_ALREADY_EXIST_CODE, - REGISTRANT_ALREADY_EXIST_MESSAGE, - REGISTRANT_ALREADY_EXIST_PARAM, -} = require('../../../constants'); -const registerForEvent = async (parent, args, context) => { - const userFound = await User.findOne({ _id: context.userId }); - if (!userFound) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - const eventFound = await Event.findOne({ _id: args.id }); - if (!eventFound) { - throw new NotFoundError( - !IN_PRODUCTION - ? EVENT_NOT_FOUND - : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM - ); - } - - const index = eventFound.registrants.findIndex((element) => { - return String(element.userId) === String(context.userId); - }); - - let isAlreadyExists = false; - if (index !== -1) { - const isActive = eventFound.registrants[index].status === 'ACTIVE'; - if (isActive) { - throw new NotFoundError( - !IN_PRODUCTION - ? REGISTRANT_ALREADY_EXIST - : requestContext.translate(REGISTRANT_ALREADY_EXIST_MESSAGE), - REGISTRANT_ALREADY_EXIST_CODE, - REGISTRANT_ALREADY_EXIST_PARAM - ); - } else { - isAlreadyExists = true; - } - } - - if (!isAlreadyExists) { - await User.findOneAndUpdate( - { - _id: userFound.id, - }, - { - $push: { - registeredEvents: eventFound, - }, - } - ); - } - - let newEvent; - if (!isAlreadyExists) { - newEvent = await Event.findOneAndUpdate( - { - _id: args.id, - status: 'ACTIVE', - }, - { - $push: { - registrants: { - userId: userFound.id, - user: userFound, - }, - }, - }, - { - new: true, - } - ); - } else { - let updatedRegistrants = eventFound.registrants; - updatedRegistrants[index] = { - id: updatedRegistrants[index].id, - userId: updatedRegistrants[index].userId, - user: updatedRegistrants[index].user, - status: 'ACTIVE', - createdAt: updatedRegistrants[index].createdAt, - }; - - newEvent = await Event.findOneAndUpdate( - { - _id: args.id, - status: 'ACTIVE', - }, - { - $set: { - registrants: updatedRegistrants, - }, - }, - { - new: true, - } - ); - } - - return newEvent; -}; - -module.exports = registerForEvent; diff --git a/lib/resolvers/event_mutations/removeEvent.js b/lib/resolvers/event_mutations/removeEvent.js deleted file mode 100644 index 204eb993f2..0000000000 --- a/lib/resolvers/event_mutations/removeEvent.js +++ /dev/null @@ -1,82 +0,0 @@ -const User = require('../../models/User'); -const Event = require('../../models/Event'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_MESSAGE, - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, -} = require('../../../constants'); - -const removeEvent = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - const event = await Event.findOne({ _id: args.id }); - if (!event) { - throw new NotFoundError( - !IN_PRODUCTION - ? EVENT_NOT_FOUND - : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM - ); - } - const isUserOrganisationAdmin = user.adminFor.includes( - event.organization.toString() - ); - - const isUserEventAdmin = event.admins.includes(context.userId.toString()); - const userCanDeleteThisEvent = isUserOrganisationAdmin || isUserEventAdmin; - - if (!userCanDeleteThisEvent) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - await User.updateMany( - { createdEvents: args.id }, - { - $pull: { - createdEvents: args.id, - }, - } - ); - - await User.updateMany( - { eventAdmin: args.id }, - { - $pull: { - eventAdmin: args.id, - }, - } - ); - - await Event.findOneAndUpdate({ _id: args.id }, { status: 'DELETED' }); - return event; -}; - -module.exports = removeEvent; diff --git a/lib/resolvers/event_mutations/unregisterForEvent.js b/lib/resolvers/event_mutations/unregisterForEvent.js deleted file mode 100644 index 8b166ca5d1..0000000000 --- a/lib/resolvers/event_mutations/unregisterForEvent.js +++ /dev/null @@ -1,101 +0,0 @@ -const User = require('../../models/User'); -const Event = require('../../models/Event'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_PARAM, - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_MESSAGE, - USER_ALREADY_UNREGISTERED, - USER_ALREADY_UNREGISTERED_MESSAGE, - USER_ALREADY_UNREGISTERED_CODE, - USER_ALREADY_UNREGISTERED_PARAM, -} = require('../../../constants'); - -const unregisterForEventByUser = async (parent, args, context) => { - const userFound = await User.findOne({ - _id: context.userId, - }); - - if (!userFound) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - const eventFound = await Event.findOne({ - _id: args.id, - }); - - if (!eventFound) { - throw new NotFoundError( - !IN_PRODUCTION - ? EVENT_NOT_FOUND - : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM - ); - } - - const index = eventFound.registrants.findIndex((element) => { - return String(element.userId) === String(context.userId); - }); - - if (index === -1) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - if (eventFound.registrants[index].status === 'ACTIVE') { - let updatedRegistrants = eventFound.registrants; - updatedRegistrants[index] = { - id: updatedRegistrants[index].id, - userId: updatedRegistrants[index].userId, - user: updatedRegistrants[index].user, - status: 'DELETED', - createdAt: updatedRegistrants[index].createdAt, - }; - - const newEvent = await Event.findOneAndUpdate( - { - _id: args.id, - status: 'ACTIVE', - }, - { - $set: { - registrants: updatedRegistrants, - }, - }, - { - new: true, - } - ); - - return newEvent; - } else { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_ALREADY_UNREGISTERED - : requestContext.translate(USER_ALREADY_UNREGISTERED_MESSAGE), - USER_ALREADY_UNREGISTERED_CODE, - USER_ALREADY_UNREGISTERED_PARAM - ); - } -}; - -module.exports = unregisterForEventByUser; diff --git a/lib/resolvers/event_mutations/updateEvent.js b/lib/resolvers/event_mutations/updateEvent.js deleted file mode 100644 index 1724cfbafd..0000000000 --- a/lib/resolvers/event_mutations/updateEvent.js +++ /dev/null @@ -1,64 +0,0 @@ -const User = require('../../models/User'); -const Event = require('../../models/Event'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_MESSAGE, - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, -} = require('../../../constants'); - -const updateEvent = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - const event = await Event.findOne({ _id: args.id }); - if (!event) { - throw new NotFoundError( - !IN_PRODUCTION - ? EVENT_NOT_FOUND - : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM - ); - } - - if (!event.admins.includes(context.userId)) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - const newEvent = await Event.findOneAndUpdate( - { _id: args.id }, - { ...args.data }, - { new: true } - ); - return { - ...newEvent._doc, - }; -}; - -module.exports = updateEvent; diff --git a/lib/resolvers/event_project_mutations/createProject.js b/lib/resolvers/event_project_mutations/createProject.js deleted file mode 100644 index 40b974bf5b..0000000000 --- a/lib/resolvers/event_project_mutations/createProject.js +++ /dev/null @@ -1,55 +0,0 @@ -const User = require('../../models/User'); -const EventProject = require('../../models/EventProject'); -const Event = require('../../models/Event'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const createEventProject = async (parent, args, context) => { - // gets user in token - to be used later on - const userFound = await User.findOne({ _id: context.userId }); - if (!userFound) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'User not found' - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const eventFound = await Event.findOne({ _id: args.data.eventId }); - if (!eventFound) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Event not found' - : requestContext.translate('event.notFound'), - 'event.notFound', - 'event' - ); - } - - if (!eventFound.admins.includes(context.userId)) { - throw new UnauthorizedError( - process.env.NODE_ENV !== 'production' - ? 'User not Authorized' - : requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - const newEventProject = new EventProject({ - title: args.data.title, - description: args.data.description, - event: eventFound, - creator: userFound, - }); - - await newEventProject.save(); - - return { - ...newEventProject._doc, - }; -}; - -module.exports = createEventProject; diff --git a/lib/resolvers/event_project_mutations/removeProject.js b/lib/resolvers/event_project_mutations/removeProject.js deleted file mode 100644 index b24f0ab379..0000000000 --- a/lib/resolvers/event_project_mutations/removeProject.js +++ /dev/null @@ -1,43 +0,0 @@ -const User = require('../../models/User'); -const EventProject = require('../../models/EventProject'); -const constants = require('../../../constants'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const removeEventProject = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !constants.IN_PRODUCTION - ? constants.USER_NOT_FOUND - : requestContext.translate(constants.USER_NOT_FOUND_MESSAGE), - constants.USER_NOT_FOUND_CODE, - constants.USER_NOT_FOUND_PARAM - ); - } - - const eventProject = await EventProject.findOne({ _id: args.id }); - if (!eventProject) { - throw new NotFoundError( - !constants.IN_PRODUCTION - ? constants.EVENT_PROJECT_NOT_FOUND - : requestContext.translate(constants.EVENT_PROJECT_NOT_FOUND_MESSAGE), - constants.EVENT_PROJECT_NOT_FOUND_CODE, - constants.EVENT_PROJECT_NOT_FOUND_PARAM - ); - } - if (`${eventProject.creator}` !== `${context.userId}`) { - throw new UnauthorizedError( - !constants.IN_PRODUCTION - ? constants.USER_NOT_AUTHORIZED - : requestContext.translate(constants.USER_NOT_AUTHORIZED_MESSAGE), - constants.USER_NOT_AUTHORIZED_CODE, - constants.USER_NOT_AUTHORIZED_PARAM - ); - } - - await EventProject.deleteOne({ _id: args.id }); - return eventProject; -}; - -module.exports = removeEventProject; diff --git a/lib/resolvers/event_project_mutations/updateProject.js b/lib/resolvers/event_project_mutations/updateProject.js deleted file mode 100644 index 5ee958f0bb..0000000000 --- a/lib/resolvers/event_project_mutations/updateProject.js +++ /dev/null @@ -1,52 +0,0 @@ -const User = require('../../models/User'); -const EventProject = require('../../models/EventProject'); - -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const updateEvent = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - - if (!user) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'User not found' - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const eventProject = await EventProject.findOne({ _id: args.id }); - - if (!eventProject) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'EventProject not found' - : requestContext.translate('eventProject.notFound'), - 'eventProject.notFound', - 'eventProject' - ); - } - - // toString() method converts mongodb's objectId to a javascript string for comparision - if (eventProject.creator.toString() !== context.userId) { - throw new UnauthorizedError( - process.env.NODE_ENV !== 'production' - ? 'User not authorized' - : requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - const newEventProject = await EventProject.findOneAndUpdate( - { _id: args.id }, - { ...args.data }, - { new: true } - ); - - return newEventProject; -}; - -module.exports = updateEvent; diff --git a/lib/resolvers/event_query/event.js b/lib/resolvers/event_query/event.js deleted file mode 100644 index a3bec4b59b..0000000000 --- a/lib/resolvers/event_query/event.js +++ /dev/null @@ -1,24 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const Event = require('../../models/Event'); - -module.exports = async (parent, args) => { - const eventFound = await Event.findOne({ - _id: args.id, - status: 'ACTIVE', - }) - .populate('creator', '-password') - .populate('tasks') - .populate('admins', '-password'); - - if (!eventFound) { - throw new NotFoundError( - requestContext.translate('event.notFound'), - 'event.notFound', - 'event' - ); - } - - return eventFound; -}; diff --git a/lib/resolvers/event_query/events.js b/lib/resolvers/event_query/events.js deleted file mode 100644 index 44ed89e6bc..0000000000 --- a/lib/resolvers/event_query/events.js +++ /dev/null @@ -1,59 +0,0 @@ -const Event = require('../../models/Event'); - -module.exports = async (parent, args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'title_ASC') { - sort = { title: 1 }; - } else if (args.orderBy === 'title_DESC') { - sort = { title: -1 }; - } else if (args.orderBy === 'description_ASC') { - sort = { description: 1 }; - } else if (args.orderBy === 'description_DESC') { - sort = { description: -1 }; - } else if (args.orderBy === 'startDate_ASC') { - sort = { startDate: 1 }; - } else if (args.orderBy === 'startDate_DESC') { - sort = { startDate: -1 }; - } else if (args.orderBy === 'endDate_ASC') { - sort = { endDate: 1 }; - } else if (args.orderBy === 'endDate_DESC') { - sort = { endDate: -1 }; - } else if (args.orderBy === 'allDay_ASC') { - sort = { allDay: 1 }; - } else if (args.orderBy === 'allDay_DESC') { - sort = { allDay: -1 }; - } else if (args.orderBy === 'startTime_ASC') { - sort = { startTime: 1 }; - } else if (args.orderBy === 'startTime_DESC') { - sort = { startTime: -1 }; - } else if (args.orderBy === 'endTime_ASC') { - sort = { endTime: 1 }; - } else if (args.orderBy === 'endTime_DESC') { - sort = { endTime: -1 }; - } else if (args.orderBy === 'recurrance_ASC') { - sort = { recurrance: 1 }; - } else if (args.orderBy === 'recurrance_DESC') { - sort = { recurrance: -1 }; - } else if (args.orderBy === 'location_ASC') { - sort = { location: 1 }; - } else { - sort = { location: -1 }; - } - } - - const eventsResponse = await Event.find({ status: 'ACTIVE' }) - .sort(sort) - .populate('creator', '-password') - .populate('tasks') - .populate('admins', '-password'); - - return eventsResponse; -}; diff --git a/lib/resolvers/event_query/eventsByOrganization.js b/lib/resolvers/event_query/eventsByOrganization.js deleted file mode 100644 index 27b0baf17b..0000000000 --- a/lib/resolvers/event_query/eventsByOrganization.js +++ /dev/null @@ -1,69 +0,0 @@ -const Event = require('../../models/Event'); -const { STATUS_ACTIVE } = require('../../../constants'); - -module.exports = async (parent, args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'title_ASC') { - sort = { title: 1 }; - } else if (args.orderBy === 'title_DESC') { - sort = { title: -1 }; - } else if (args.orderBy === 'description_ASC') { - sort = { description: 1 }; - } else if (args.orderBy === 'description_DESC') { - sort = { description: -1 }; - } else if (args.orderBy === 'startDate_ASC') { - sort = { startDate: 1 }; - } else if (args.orderBy === 'startDate_DESC') { - sort = { startDate: -1 }; - } else if (args.orderBy === 'endDate_ASC') { - sort = { endDate: 1 }; - } else if (args.orderBy === 'endDate_DESC') { - sort = { endDate: -1 }; - } else if (args.orderBy === 'allDay_ASC') { - sort = { allDay: 1 }; - } else if (args.orderBy === 'allDay_DESC') { - sort = { allDay: -1 }; - } else if (args.orderBy === 'startTime_ASC') { - sort = { startTime: 1 }; - } else if (args.orderBy === 'startTime_DESC') { - sort = { startTime: -1 }; - } else if (args.orderBy === 'endTime_ASC') { - sort = { endTime: 1 }; - } else if (args.orderBy === 'endTime_DESC') { - sort = { endTime: -1 }; - } else if (args.orderBy === 'recurrance_ASC') { - sort = { recurrance: 1 }; - } else if (args.orderBy === 'recurrance_DESC') { - sort = { recurrance: -1 }; - } else if (args.orderBy === 'location_ASC') { - sort = { location: 1 }; - } else { - sort = { location: -1 }; - } - } - - const eventResponse = await Event.find({ - organization: args.id, - status: 'ACTIVE', - }) - .sort(sort) - .populate('creator', '-password') - .populate('tasks') - .populate('admins', '-password'); - - eventResponse.forEach((event) => { - event.registrants = event.registrants.filter( - (registrant) => registrant.status === STATUS_ACTIVE - ); - }); - - return eventResponse; -}; diff --git a/lib/resolvers/event_query/isUserRegister.js b/lib/resolvers/event_query/isUserRegister.js deleted file mode 100644 index adcea00232..0000000000 --- a/lib/resolvers/event_query/isUserRegister.js +++ /dev/null @@ -1,46 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_MESSAGE, - EVENT_NOT_FOUND_PARAM, -} = require('../../../constants'); -const Event = require('../../models/Event'); - -module.exports = async (parent, args, context) => { - const eventFound = await Event.findOne({ - _id: args.eventId, - status: 'ACTIVE', - }) - .populate('creator', '-password') - .populate('tasks') - .populate('admins', '-password'); - - if (!eventFound) { - throw new NotFoundError( - !IN_PRODUCTION - ? EVENT_NOT_FOUND - : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM - ); - } - - let isRegistered = false; - for (const registrant of eventFound.registrants) { - if ( - registrant.userId === context.userId && - registrant.status === 'ACTIVE' - ) { - isRegistered = true; - break; - } - } - - return { - event: eventFound, - isRegistered: isRegistered, - }; -}; diff --git a/lib/resolvers/event_query/registeredEventsByUser.js b/lib/resolvers/event_query/registeredEventsByUser.js deleted file mode 100644 index 95800b3965..0000000000 --- a/lib/resolvers/event_query/registeredEventsByUser.js +++ /dev/null @@ -1,65 +0,0 @@ -const Event = require('../../models/Event'); - -module.exports = async (parent, args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'title_ASC') { - sort = { title: 1 }; - } else if (args.orderBy === 'title_DESC') { - sort = { title: -1 }; - } else if (args.orderBy === 'description_ASC') { - sort = { description: 1 }; - } else if (args.orderBy === 'description_DESC') { - sort = { description: -1 }; - } else if (args.orderBy === 'startDate_ASC') { - sort = { startDate: 1 }; - } else if (args.orderBy === 'startDate_DESC') { - sort = { startDate: -1 }; - } else if (args.orderBy === 'endDate_ASC') { - sort = { endDate: 1 }; - } else if (args.orderBy === 'endDate_DESC') { - sort = { endDate: -1 }; - } else if (args.orderBy === 'allDay_ASC') { - sort = { allDay: 1 }; - } else if (args.orderBy === 'allDay_DESC') { - sort = { allDay: -1 }; - } else if (args.orderBy === 'startTime_ASC') { - sort = { startTime: 1 }; - } else if (args.orderBy === 'startTime_DESC') { - sort = { startTime: -1 }; - } else if (args.orderBy === 'endTime_ASC') { - sort = { endTime: 1 }; - } else if (args.orderBy === 'endTime_DESC') { - sort = { endTime: -1 }; - } else if (args.orderBy === 'recurrance_ASC') { - sort = { recurrance: 1 }; - } else if (args.orderBy === 'recurrance_DESC') { - sort = { recurrance: -1 }; - } else if (args.orderBy === 'location_ASC') { - sort = { location: 1 }; - } else { - sort = { location: -1 }; - } - } - - return await Event.find({ - status: 'ACTIVE', - registrants: { - $elemMatch: { - userId: args.id, - status: 'ACTIVE', - }, - }, - }) - .sort(sort) - .populate('creator', '-password') - .populate('tasks') - .populate('admins', '-password'); -}; diff --git a/lib/resolvers/event_query/registrantsByEvent.js b/lib/resolvers/event_query/registrantsByEvent.js deleted file mode 100644 index 3a303207a7..0000000000 --- a/lib/resolvers/event_query/registrantsByEvent.js +++ /dev/null @@ -1,43 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const Event = require('../../models/Event'); -const { - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_MESSAGE, - EVENT_NOT_FOUND_PARAM, - EVENT_NOT_FOUND_CODE, - IN_PRODUCTION, -} = require('../../../constants'); - -module.exports = async (parent, args) => { - const eventFound = await Event.findOne({ - _id: args.id, - status: 'ACTIVE', - }).populate('registrants.user'); - - if (!eventFound) { - throw new NotFoundError( - !IN_PRODUCTION - ? EVENT_NOT_FOUND - : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM - ); - } - - // Return EventFound Registrants - let registrants = []; - if (eventFound.registrants.length > 0) { - eventFound.registrants.map((registrant) => { - if (registrant.status === 'ACTIVE') { - registrants.push({ - ...registrant.user._doc, - password: null, - }); - } - }); - } - - return registrants; -}; diff --git a/lib/resolvers/event_query/tasksByEvent.js b/lib/resolvers/event_query/tasksByEvent.js deleted file mode 100644 index ba95ce68db..0000000000 --- a/lib/resolvers/event_query/tasksByEvent.js +++ /dev/null @@ -1,36 +0,0 @@ -const Task = require('../../models/Task'); - -module.exports = async (parent, args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'title_ASC') { - sort = { title: 1 }; - } else if (args.orderBy === 'title_DESC') { - sort = { title: -1 }; - } else if (args.orderBy === 'description_ASC') { - sort = { description: 1 }; - } else if (args.orderBy === 'description_DESC') { - sort = { description: -1 }; - } else if (args.orderBy === 'createdAt_ASC') { - sort = { createdAt: 1 }; - } else if (args.orderBy === 'createdAt_DESC') { - sort = { createdAt: -1 }; - } else if (args.orderBy === 'deadline_ASC') { - sort = { deadline: 1 }; - } else { - sort = { deadline: -1 }; - } - } - - return await Task.find({ event: args.id }) - .sort(sort) - .populate('event') - .populate('creator', '-password'); -}; diff --git a/lib/resolvers/functions/adminCheck.js b/lib/resolvers/functions/adminCheck.js deleted file mode 100644 index 9e57abacb3..0000000000 --- a/lib/resolvers/functions/adminCheck.js +++ /dev/null @@ -1,24 +0,0 @@ -const { UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, -} = require('../../../constants'); - -const adminCheck = (context, org) => { - const isAdmin = org.admins.includes(context.userId); - if (!isAdmin) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } -}; - -module.exports = adminCheck; diff --git a/lib/resolvers/functions/copyToClipboard.js b/lib/resolvers/functions/copyToClipboard.js deleted file mode 100644 index d93e3d5f9c..0000000000 --- a/lib/resolvers/functions/copyToClipboard.js +++ /dev/null @@ -1,8 +0,0 @@ -const ncp = require('copy-paste'); - -module.exports = (text) => { - // Only copies in development or test mode - if (process.env.NODE_ENV !== 'production') { - ncp.copy(text); - } -}; diff --git a/lib/resolvers/functions/creatorCheck.js b/lib/resolvers/functions/creatorCheck.js deleted file mode 100644 index b92b44d8c2..0000000000 --- a/lib/resolvers/functions/creatorCheck.js +++ /dev/null @@ -1,24 +0,0 @@ -const { UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, - IN_PRODUCTION, -} = require('../../../constants'); - -const creatorCheck = (context, org) => { - const isCreator = String(org.creator) === context.userId; - if (!isCreator) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } -}; - -module.exports = creatorCheck; diff --git a/lib/resolvers/functions/superAdminCheck.js b/lib/resolvers/functions/superAdminCheck.js deleted file mode 100644 index b87be1bde1..0000000000 --- a/lib/resolvers/functions/superAdminCheck.js +++ /dev/null @@ -1,17 +0,0 @@ -const { UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const superAdminCheck = (context, user) => { - const isSuperAdmin = user.userType === 'SUPERADMIN'; - if (!isSuperAdmin) { - throw new UnauthorizedError( - process.env.NODE_ENV !== 'production' - ? 'User is not authorized for performing this operation' - : requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } -}; - -module.exports = superAdminCheck; diff --git a/lib/resolvers/group_chat_mutations/addUserToGroupChat.js b/lib/resolvers/group_chat_mutations/addUserToGroupChat.js deleted file mode 100644 index f57ea479e9..0000000000 --- a/lib/resolvers/group_chat_mutations/addUserToGroupChat.js +++ /dev/null @@ -1,62 +0,0 @@ -const User = require('../../models/User'); -const GroupChat = require('../../models/GroupChat'); -const adminCheck = require('../functions/adminCheck'); -const organizationExists = require('../../helper_functions/organizationExists'); -const { NotFoundError, ConflictError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - CHAT_NOT_FOUND, - CHAT_NOT_FOUND_MESSAGE, - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM, - USER_ALREADY_MEMBER, - USER_ALREADY_MEMBER_CODE, - USER_ALREADY_MEMBER_MESSAGE, - USER_ALREADY_MEMBER_PARAM, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - let chat = await GroupChat.findById(args.chatId); - if (!chat) { - throw new NotFoundError( - !IN_PRODUCTION - ? CHAT_NOT_FOUND - : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM - ); - } - - const org = await organizationExists(chat.organization); - - adminCheck(context, org); // only an admin can add new users to the group chat -- may change in the future - - const userBeingAdded = await User.findById(args.userId); - - // ensure user isnt already a member - const userAlreadyAMember = chat._doc.users.filter( - (user) => user.toString() === args.userId.toString() - ); - if (userAlreadyAMember.length > 0) { - throw new ConflictError( - !IN_PRODUCTION - ? USER_ALREADY_MEMBER - : requestContext.translate(USER_ALREADY_MEMBER_MESSAGE), - USER_ALREADY_MEMBER_CODE, - USER_ALREADY_MEMBER_PARAM - ); - } - - return await GroupChat.findOneAndUpdate( - { _id: args.chatId }, - { - $set: { - users: [...chat._doc.users, userBeingAdded], - }, - }, - { - new: true, - } - ); -}; diff --git a/lib/resolvers/group_chat_mutations/createGroupChat.js b/lib/resolvers/group_chat_mutations/createGroupChat.js deleted file mode 100644 index 7e2b083145..0000000000 --- a/lib/resolvers/group_chat_mutations/createGroupChat.js +++ /dev/null @@ -1,51 +0,0 @@ -const User = require('../../models/User'); -const GroupChat = require('../../models/GroupChat'); -const Organization = require('../../models/Organization'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - const userFound = await User.findOne({ _id: context.userId }); - if (!userFound) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const org = await Organization.findOne({ _id: args.data.organizationId }); - if (!org) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - const usersInChat = []; - - // add users to cat - for await (const userId of args.data.userIds) { - const user = await await User.findOne({ _id: userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - usersInChat.push(user); - } - - let groupChat = new GroupChat({ - creator: userFound, - users: usersInChat, - organization: org, - title: args.data.title, - }); - - groupChat = await groupChat.save(); - - return groupChat._doc; -}; diff --git a/lib/resolvers/group_chat_mutations/removeGroupChat.js b/lib/resolvers/group_chat_mutations/removeGroupChat.js deleted file mode 100644 index 8ccd433fce..0000000000 --- a/lib/resolvers/group_chat_mutations/removeGroupChat.js +++ /dev/null @@ -1,34 +0,0 @@ -const GroupChat = require('../../models/GroupChat'); -const GroupChatMessage = require('../../models/GroupChatMessage'); -const adminCheck = require('../functions/adminCheck'); -const organizationExists = require('../../helper_functions/organizationExists'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -// admins of the organization can remove chats -- may change in the future - -module.exports = async (parent, args, context) => { - const chat = await GroupChat.findById(args.chatId); - if (!chat) { - throw new NotFoundError( - requestContext.translate('chat.notFound'), - 'chat.notFound', - 'chat' - ); - } - - const org = await organizationExists(chat.organization); - - adminCheck(context, org); - - // delete all messages in the chat - await GroupChatMessage.deleteMany({ - _id: { - $in: [...chat.messages], - }, - }); - - await GroupChat.deleteOne({ _id: args.chatId }); - - return chat; -}; diff --git a/lib/resolvers/group_chat_mutations/removeUserFromGroupChat.js b/lib/resolvers/group_chat_mutations/removeUserFromGroupChat.js deleted file mode 100644 index db7cad301e..0000000000 --- a/lib/resolvers/group_chat_mutations/removeUserFromGroupChat.js +++ /dev/null @@ -1,46 +0,0 @@ -const GroupChat = require('../../models/GroupChat'); -const adminCheck = require('../functions/adminCheck'); -const organizationExists = require('../../helper_functions/organizationExists'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - const chat = await GroupChat.findById(args.chatId); - if (!chat) { - throw new NotFoundError( - requestContext.translate('chat.notFound'), - 'chat.notFound', - 'chat' - ); - } - - const org = await organizationExists(chat.organization); - - adminCheck(context, org); // only an admin can add new users to the group chat -- may change in the future - - // ensure user is already a member - const userAlreadyAMember = chat._doc.users.filter( - (user) => user === args.userId - ); - if (!(userAlreadyAMember.length > 0)) { - throw new UnauthorizedError( - requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - return await GroupChat.findOneAndUpdate( - { - _id: args.chatId, - }, - { - $set: { - users: chat._doc.users.filter((user) => user !== args.userId), - }, - }, - { - new: true, - } - ); -}; diff --git a/lib/resolvers/group_chat_mutations/sendMessageToGroupChat.js b/lib/resolvers/group_chat_mutations/sendMessageToGroupChat.js deleted file mode 100644 index dfbd251691..0000000000 --- a/lib/resolvers/group_chat_mutations/sendMessageToGroupChat.js +++ /dev/null @@ -1,75 +0,0 @@ -const GroupChat = require('../../models/GroupChat'); -const GroupChatMessage = require('../../models/GroupChatMessage'); -const userExists = require('../../helper_functions/userExists'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_MESSAGE, - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM, - CHAT_NOT_FOUND, - CHAT_NOT_FOUND_PARAM, - CHAT_NOT_FOUND_MESSAGE, - CHAT_NOT_FOUND_CODE, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - const chat = await GroupChat.findById(args.chatId); - if (!chat) { - throw new NotFoundError( - !IN_PRODUCTION - ? CHAT_NOT_FOUND - : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), - CHAT_NOT_FOUND_CODE, - CHAT_NOT_FOUND_PARAM - ); - } - - const sender = await userExists(context.userId); - - // ensure the user is a member of the group chat - const userIsAMemberOfGroupChat = chat.users.filter( - (user) => user.toString() === context.userId - ); - if (!(userIsAMemberOfGroupChat.length > 0)) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - const message = new GroupChatMessage({ - groupChatMessageBelongsTo: chat._doc, - sender: sender._id, - createdAt: new Date(), - messageContent: args.messageContent, - }); - - await message.save(); - - // add message to chat - await GroupChat.updateOne( - { - _id: args.chatId, - }, - { - $set: { - messages: [...chat._doc.messages, message], - }, - } - ); - - //calls subscription - context.pubsub.publish('MESSAGE_SENT_TO_GROUP_CHAT', { - messageSentToGroupChat: { - ...message._doc, - }, - }); - - return message._doc; -}; diff --git a/lib/resolvers/group_chat_query/groupChatMessages.js b/lib/resolvers/group_chat_query/groupChatMessages.js deleted file mode 100644 index ae73c079c1..0000000000 --- a/lib/resolvers/group_chat_query/groupChatMessages.js +++ /dev/null @@ -1,5 +0,0 @@ -const GroupChatMessages = require('../../models/GroupChatMessage'); - -module.exports = async () => { - return await GroupChatMessages.find(); -}; diff --git a/lib/resolvers/group_chat_query/groupChats.js b/lib/resolvers/group_chat_query/groupChats.js deleted file mode 100644 index d39b88f274..0000000000 --- a/lib/resolvers/group_chat_query/groupChats.js +++ /dev/null @@ -1,5 +0,0 @@ -const GroupChat = require('../../models/GroupChat'); - -module.exports = async () => { - return await GroupChat.find(); -}; diff --git a/lib/resolvers/group_query/groups.js b/lib/resolvers/group_query/groups.js deleted file mode 100644 index 0fb898f6b8..0000000000 --- a/lib/resolvers/group_query/groups.js +++ /dev/null @@ -1,5 +0,0 @@ -const Group = require('../../models/Group'); - -module.exports = async () => { - return await Group.find(); -}; diff --git a/lib/resolvers/language_maintainer_mutation/addLanguageTranslation.js b/lib/resolvers/language_maintainer_mutation/addLanguageTranslation.js deleted file mode 100644 index a665609dcb..0000000000 --- a/lib/resolvers/language_maintainer_mutation/addLanguageTranslation.js +++ /dev/null @@ -1,57 +0,0 @@ -const { ConflictError } = require('errors'); -const Language = require('../../models/Language'); -const requestContext = require('talawa-request-context'); - -const addLanguageTranslation = async (parent, args) => { - const langValue = await Language.findOne({ - en: args.data.en_value, - }); - - if (langValue) { - langValue.translation.forEach((element) => { - if (element.lang_code === args.data.translation_lang_code) { - throw new ConflictError( - process.env.NODE_ENV !== 'production' - ? 'Already Present' - : requestContext.translate('translation.alreadyPresent'), - 'translation.alreadyPresent', - 'translationAlreadyPresent' - ); - } - }); - - const filter = { - en: args.data.en_value, - }; - - const update = { - $push: { - translation: { - lang_code: args.data.translation_lang_code, - value: args.data.translation_value, - }, - }, - }; - - const langUpdate = await Language.findOneAndUpdate(filter, update, { - new: true, - }); - - return langUpdate; - } - - let lang = new Language({ - en: args.data.en_value, - translation: [ - { - lang_code: args.data.translation_lang_code, - value: args.data.translation_value, - }, - ], - }); - - lang = await lang.save(); - return lang._doc; -}; - -module.exports = addLanguageTranslation; diff --git a/lib/resolvers/language_maintainer_query/getlanguage.js b/lib/resolvers/language_maintainer_query/getlanguage.js deleted file mode 100644 index 4fbab903aa..0000000000 --- a/lib/resolvers/language_maintainer_query/getlanguage.js +++ /dev/null @@ -1,39 +0,0 @@ -const Language = require('../../models/Language'); -//const { NotFoundError } = require('errors'); -//const requestContext = require('talawa-request-context'); - -const getLanguage = async (parent, args) => { - const translationFound = await Language.find({ - 'translation.lang_code': args.lang_code, - }); - - // THE ERROR CASE IS NOT POSSIBLE AS QUERY WILL RETURN EMPTY ARRAY - // - // if (!translationFound) { - // throw new NotFoundError( - // process.env.NODE_ENV !== 'production' - // ? 'Translation not found' - // : requestContext.translate('translation.notFound'), - // 'translation.notFound', - // 'translationNotFound' - // ); - // } - - let languages = []; - translationFound.forEach((element) => { - element.translation.forEach((translated) => { - if (translated.lang_code === args.lang_code) { - languages.push({ - lang_code: translated.lang_code, - en_value: element.en, - translation: translated.value, - verified: translated.verified, - }); - } - }); - }); - - return languages; -}; - -module.exports = getLanguage; diff --git a/lib/resolvers/language_mutation/updateLanguage.js b/lib/resolvers/language_mutation/updateLanguage.js deleted file mode 100644 index 76caddb78f..0000000000 --- a/lib/resolvers/language_mutation/updateLanguage.js +++ /dev/null @@ -1,31 +0,0 @@ -const User = require('../../models/User'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const updateLanguage = async (parent, args, context) => { - // gets user in token - to be used later on - const userFound = await User.findOne({ - _id: context.userId, - }); - if (!userFound) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'User not found' - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - //UPDATE LANGUAGE - userFound.overwrite({ - ...userFound._doc, - appLanguageCode: args.languageCode, - }); - - await userFound.save(); - - return userFound; -}; - -module.exports = updateLanguage; diff --git a/lib/resolvers/member_mutations/join_public_organization.js b/lib/resolvers/member_mutations/join_public_organization.js deleted file mode 100644 index 82925f00c6..0000000000 --- a/lib/resolvers/member_mutations/join_public_organization.js +++ /dev/null @@ -1,67 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const { NotFoundError, ConflictError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - // ensure organization exists - const org = await Organization.findOne({ _id: args.organizationId }); - if (!org) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - // ensures organization is public - if (!org._doc.isPublic) { - throw new UnauthorizedError( - requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - // ensure user exists - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - // check to see if user is already a member - const members = org._doc.members.filter( - (member) => member.toString() === user.id - ); - if (members.length !== 0) { - throw new ConflictError( - requestContext.translate('user.alreadyMember'), - 'user.alreadyMember', - 'userAlreadyMember' - ); - } - - // add user to organization's members field - org.overwrite({ - ...org._doc, - members: [...org._doc.members, user], - }); - await org.save(); - - // add organization to user's joined organization field - user.overwrite({ - ...user._doc, - joinedOrganizations: [...user._doc.joinedOrganizations, org], - }); - await user.save(); - - // return user - return { - ...user._doc, - password: null, - }; -}; diff --git a/lib/resolvers/member_mutations/leave_organization.js b/lib/resolvers/member_mutations/leave_organization.js deleted file mode 100644 index 2e9c92d271..0000000000 --- a/lib/resolvers/member_mutations/leave_organization.js +++ /dev/null @@ -1,91 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const { NotFoundError, UnauthorizedError, ConflictError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - MEMBER_NOT_FOUND_MESSAGE, - MEMBER_NOT_FOUND_PARAM, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, - USER_NOT_AUTHORIZED_PARAM, - MEMBER_NOT_FOUND_CODE, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_CODE, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - //ensure organization exists - let org = await Organization.findOne({ _id: args.organizationId }); - if (!org) { - throw new NotFoundError( - requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - //ensure user exists - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - //checks to see if the user trying to leave is the owner of the organization - if (user.id === org._doc.creator) { - throw new UnauthorizedError( - requestContext.translate(USER_NOT_AUTHORIZED), - USER_NOT_AUTHORIZED_CODE, - USER_NOT_AUTHORIZED_PARAM - ); - } - - //check to see if user is already a member - const members = org._doc.members.filter( - (member) => member.toString() === user.id - ); - console.log(members); - if (members.length === 0) { - throw new ConflictError( - requestContext.translate(MEMBER_NOT_FOUND_MESSAGE), - MEMBER_NOT_FOUND_CODE, - MEMBER_NOT_FOUND_PARAM - ); - } - - //if the user is an admin he is removed from the organization's admin field - org.overwrite({ - ...org._doc, - admins: org._doc.admins.filter((admin) => admin.toString() !== user.id), - }); - await org.save(); - - //remove user from the organization's members field - org.overwrite({ - ...org._doc, - members: org._doc.members.filter((member) => member.toString() !== user.id), - }); - await org.save(); - - //remove organization from user's joined organization field - user.overwrite({ - ...user._doc, - joinedOrganizations: user._doc.joinedOrganizations.filter( - (organization) => organization.toString() !== org.id - ), - }); - await user.save(); - - //return user - return { - ...user._doc, - password: null, - }; -}; diff --git a/lib/resolvers/member_mutations/removeMember.js b/lib/resolvers/member_mutations/removeMember.js deleted file mode 100644 index 427c443442..0000000000 --- a/lib/resolvers/member_mutations/removeMember.js +++ /dev/null @@ -1,89 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const adminCheck = require('../functions/adminCheck'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { MEMBER_NOT_FOUND, USER_NOT_FOUND } = require('../../../constants'); - -module.exports = async (parent, args, context) => { - //ensure organization exists - let org = await Organization.findOne({ _id: args.data.organizationId }); - if (!org) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - //ensure user is an admin - adminCheck(context, org); - - let errors = []; - - for await (const userId of args.data.userIds) { - // do not run an async function inside a for each loop - it doesnt work - //ensure user exists - const user = await User.findOne({ _id: userId }); - // Errors inside a loop stop the loop it doesnt throw the error, errors have to be stored in an array an thrown at the end - if (!user) { - errors.push(USER_NOT_FOUND); - break; - } - //ensure member being removed by admin is already a member - const members = org._doc.members.filter( - (member) => member.toString() === user.id - ); - if (members.length === 0) { - errors.push(MEMBER_NOT_FOUND); - break; - } - - //ensure the user the admin is trying to remove isn't an admin - if (org._doc.admins.includes(user.id)) { - errors.push( - 'Administrators cannot remove members who are also Administrators' - ); - break; - } - - //ensure the user the admin is trying to remove isn't the creator - if (org._doc.creator === user.id) { - errors.push( - 'Administratos cannot remove the creator of the organization from the organization' - ); - break; - } - - //remove member from organization - org = await Organization.findOneAndUpdate( - { _id: org.id }, - { - $set: { - members: org._doc.members.filter( - (member) => member.toString() !== user.id - ), - }, - }, - { - new: true, - } - ); - - //remove org from user - await User.findOneAndUpdate( - { _id: user.id }, - { - $set: { - joinedOrganizations: user._doc.joinedOrganizations.filter( - (organization) => organization.toString() !== org.id - ), - }, - } - ); - } - - if (errors.length > 0) throw new Error(errors.join()); - - return org; -}; diff --git a/lib/resolvers/membership_request_mutations/accept_membership_request.js b/lib/resolvers/membership_request_mutations/accept_membership_request.js deleted file mode 100644 index ad60586de4..0000000000 --- a/lib/resolvers/membership_request_mutations/accept_membership_request.js +++ /dev/null @@ -1,91 +0,0 @@ -const adminCheck = require('../functions/adminCheck'); -const MembershipRequest = require('../../models/MembershipRequest'); -const userExists = require('../../helper_functions/userExists'); -const organizationExists = require('../../helper_functions/organizationExists'); -const { NotFoundError, ConflictError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const { - MEMBERSHIP_REQUEST_NOT_FOUND, - MEMBERSHIP_REQUEST_NOT_FOUND_CODE, - MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE, - MEMBERSHIP_REQUEST_NOT_FOUND_PARAM, - - USER_ALREADY_MEMBER, - USER_ALREADY_MEMBER_CODE, - USER_ALREADY_MEMBER_MESSAGE, - USER_ALREADY_MEMBER_PARAM, - - IN_PRODUCTION, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - //ensure membership request exists - const membershipRequest = await MembershipRequest.findOne({ - _id: args.membershipRequestId, - }); - if (!membershipRequest) { - throw new NotFoundError( - !IN_PRODUCTION - ? MEMBERSHIP_REQUEST_NOT_FOUND - : requestContext.translate(MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE), - MEMBERSHIP_REQUEST_NOT_FOUND_CODE, - MEMBERSHIP_REQUEST_NOT_FOUND_PARAM - ); - } - - //ensure org exists - let org = await organizationExists(membershipRequest.organization); - - //ensure user exists - let user = await userExists(membershipRequest.user); - - //ensure user is admin - adminCheck(context, org); - - //check to see if user is already a member - org._doc.members.forEach((member) => { - if (member._id.toString() === user._id.toString()) { - throw new ConflictError( - !IN_PRODUCTION - ? USER_ALREADY_MEMBER - : requestContext.translate(USER_ALREADY_MEMBER_MESSAGE), - USER_ALREADY_MEMBER_CODE, - USER_ALREADY_MEMBER_PARAM - ); - } - }); - - //add user in membership request as a member to the organization - org.overwrite({ - ...org._doc, - members: [...org._doc.members, user], - }); - - //delete membership request - await MembershipRequest.deleteOne({ _id: args.membershipRequestId }); - - //remove membership request from organization - org.overwrite({ - ...org._doc, - membershipRequests: org._doc.membershipRequests.filter( - (request) => request._id.toString() !== membershipRequest._id.toString() - ), - }); - - await org.save(); - - //remove membership request from user - user.overwrite({ - ...user._doc, - joinedOrganizations: [...user._doc.joinedOrganizations, org._id], - membershipRequests: user._doc.membershipRequests.filter( - (request) => request._id.toString() !== membershipRequest._id.toString() - ), - }); - - await user.save(); - - //return membershipship request - return membershipRequest._doc; -}; diff --git a/lib/resolvers/membership_request_mutations/cancel_membership_request.js b/lib/resolvers/membership_request_mutations/cancel_membership_request.js deleted file mode 100644 index db446a8b6a..0000000000 --- a/lib/resolvers/membership_request_mutations/cancel_membership_request.js +++ /dev/null @@ -1,92 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const MembershipRequest = require('../../models/MembershipRequest'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - MEMBERSHIP_REQUEST_NOT_FOUND, - ORGANIZATION_NOT_FOUND, - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - //ensure request exists - const membershipRequest = await MembershipRequest.findOne({ - _id: args.membershipRequestId, - }); - if (!membershipRequest) { - throw new NotFoundError( - !IN_PRODUCTION - ? MEMBERSHIP_REQUEST_NOT_FOUND - : requestContext.translate('membershipRequest.notFound'), - 'membershipRequest.notFound', - 'membershipRequest' - ); - } - - //ensure org exists - let org = await Organization.findOne({ - _id: membershipRequest.organization, - }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - //ensure user exists - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - //ensure user in context created membership request - const owner = user.id === membershipRequest.user.toString(); - if (!owner) { - throw new UnauthorizedError( - !IN_PRODUCTION - ? USER_NOT_AUTHORIZED - : requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - //delete membership request - await MembershipRequest.deleteOne({ _id: args.membershipRequestId }); - - //remove membership request from organization - org.overwrite({ - ...org._doc, - membershipRequests: org._doc.membershipRequests.filter( - (request) => request._id !== membershipRequest.id - ), - }); - - await org.save(); - - //remove membership request from user - user.overwrite({ - ...user._doc, - membershipRequests: user._doc.membershipRequests.filter( - (request) => request._id !== membershipRequest.id - ), - }); - - await user.save(); - - //return membership request - return membershipRequest._doc; -}; diff --git a/lib/resolvers/membership_request_mutations/reject_membership_request.js b/lib/resolvers/membership_request_mutations/reject_membership_request.js deleted file mode 100644 index 79bebd3504..0000000000 --- a/lib/resolvers/membership_request_mutations/reject_membership_request.js +++ /dev/null @@ -1,97 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const MembershipRequest = require('../../models/MembershipRequest'); -const adminCheck = require('../functions/adminCheck'); -const { NotFoundError } = require('errors'); - -const { - MEMBERSHIP_REQUEST_NOT_FOUND, - MEMBERSHIP_REQUEST_NOT_FOUND_CODE, - MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE, - MEMBERSHIP_REQUEST_NOT_FOUND_PARAM, - IN_PRODUCTION, - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_PARAM, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, -} = require('../../../constants'); - -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - //ensure membership request exists - const membershipRequest = await MembershipRequest.findOne({ - _id: args.membershipRequestId, - }); - if (!membershipRequest) { - throw new NotFoundError( - !IN_PRODUCTION - ? MEMBERSHIP_REQUEST_NOT_FOUND - : requestContext.translate(MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE), - MEMBERSHIP_REQUEST_NOT_FOUND_CODE, - MEMBERSHIP_REQUEST_NOT_FOUND_PARAM - ); - } - - //ensure org exists - let org = await Organization.findOne({ - _id: membershipRequest.organization, - }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - const user = await User.findOne({ - _id: membershipRequest.user, - }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - //ensure user is admin - adminCheck(context, org); - - //delete membership request - await MembershipRequest.deleteOne({ - _id: args.membershipRequestId, - }); - - //remove membership request from organization - org.overwrite({ - ...org._doc, - membershipRequests: org._doc.membershipRequests.filter( - (request) => request._id.toString() !== membershipRequest._id.toString() - ), - }); - - await org.save(); - - //remove membership request from user - user.overwrite({ - ...user._doc, - membershipRequests: user._doc.membershipRequests.filter( - (request) => request._id.toString() !== membershipRequest._id.toString() - ), - }); - - await user.save(); - - //return membershipship request - return membershipRequest._doc; -}; diff --git a/lib/resolvers/membership_request_mutations/send_membership_request.js b/lib/resolvers/membership_request_mutations/send_membership_request.js deleted file mode 100644 index 39b2ea0b3f..0000000000 --- a/lib/resolvers/membership_request_mutations/send_membership_request.js +++ /dev/null @@ -1,75 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const MembershipRequest = require('../../models/MembershipRequest'); -const { NotFoundError, ConflictError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - // ensure user exists - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - // ensure organization exists - const org = await Organization.findOne({ _id: args.organizationId }); - if (!org) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - // create membership request - const exists = await MembershipRequest.find({ - user: user.id, - organization: org.id, - }); - console.log(exists); - if (exists.length > 0) { - throw new ConflictError( - requestContext.translate('membershipRequest.alreadyExists'), - 'membershipRequest.alreadyExists', - 'membershipRequest' - ); - } - - let newMembershipRequest = new MembershipRequest({ - user, - organization: org, - }); - newMembershipRequest = await newMembershipRequest.save(); - - // add membership request to organization - await Organization.findOneAndUpdate( - { _id: org._doc._id }, - { - $set: { - membershipRequests: [ - ...org._doc.membershipRequests, - newMembershipRequest, - ], - }, - } - ); - - // add membership request to user - await User.findOneAndUpdate( - { _id: user._doc._id }, - { - $set: { - membershipRequests: [ - ...user._doc.membershipRequests, - newMembershipRequest, - ], - }, - } - ); - - return newMembershipRequest._doc; -}; diff --git a/lib/resolvers/message_chat_mutation/createMessageChat.js b/lib/resolvers/message_chat_mutation/createMessageChat.js deleted file mode 100644 index cf3ade0f49..0000000000 --- a/lib/resolvers/message_chat_mutation/createMessageChat.js +++ /dev/null @@ -1,41 +0,0 @@ -const User = require('../../models/User'); -const MessageChat = require('../../models/Chat'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - const user = await User.findOne({ - _id: args.data.receiver, - }); - - const senderUser = await User.findOne({ - _id: context.userId, - }); - - const isLangSame = user.appLanguageCode === senderUser.appLanguageCode; - - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - let messageChat = new MessageChat({ - sender: context.userId, - receiver: user.id, - message: args.data.message, - languageBarrier: !isLangSame, - }); - - messageChat = await messageChat.save(); - - context.pubsub.publish('CHAT_CHANNEL', { - directMessageChat: { - ...messageChat._doc, - }, - }); - - return messageChat._doc; -}; diff --git a/lib/resolvers/organization_image_mutations/add_organization_image.js b/lib/resolvers/organization_image_mutations/add_organization_image.js deleted file mode 100644 index 8433d9e681..0000000000 --- a/lib/resolvers/organization_image_mutations/add_organization_image.js +++ /dev/null @@ -1,47 +0,0 @@ -const Organization = require('../../models/Organization'); -const User = require('../../models/User'); -const adminCheck = require('../functions/adminCheck'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const uploadImage = require('../../helper_functions/uploadImage'); - -module.exports = async (parent, args, context) => { - const user = await User.findById(context.userId); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const org = await Organization.findById(args.organizationId); - if (!org) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - adminCheck(context, org); // Ensures user is an administrator of the organization - - // Upload Image - let uploadImageObj = await uploadImage(args.file, org.image); - - const newOrganization = await Organization.findOneAndUpdate( - { _id: org.id }, - { - $set: { - image: uploadImageObj.imageAlreadyInDbPath - ? uploadImageObj.imageAlreadyInDbPath - : uploadImageObj.newImagePath, - }, - }, - { - new: true, - } - ); - - return newOrganization; -}; diff --git a/lib/resolvers/organization_image_mutations/remove_organization_image.js b/lib/resolvers/organization_image_mutations/remove_organization_image.js deleted file mode 100644 index c63c587070..0000000000 --- a/lib/resolvers/organization_image_mutations/remove_organization_image.js +++ /dev/null @@ -1,53 +0,0 @@ -const Organization = require('../../models/Organization'); -const User = require('../../models/User'); -const adminCheck = require('../functions/adminCheck'); -const deleteImage = require('../../helper_functions/deleteImage'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - const user = await User.findById(context.userId); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const org = await Organization.findById(args.organizationId); - if (!org) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - adminCheck(context, org); // Ensures user is an administrator of the organization - - if (!org.image) { - throw new NotFoundError( - requestContext.translate('organization.profile.notFound'), - 'organization.notFound', - 'organization' - ); - } - - await deleteImage(org.image); - - const newOrganization = await Organization.findOneAndUpdate( - { - _id: org.id, - }, - { - $set: { - image: null, - }, - }, - { - new: true, - } - ); - return newOrganization; -}; diff --git a/lib/resolvers/organization_mutations/createOrganization.js b/lib/resolvers/organization_mutations/createOrganization.js deleted file mode 100644 index 5c68aa4b91..0000000000 --- a/lib/resolvers/organization_mutations/createOrganization.js +++ /dev/null @@ -1,50 +0,0 @@ -const User = require('../../models/User'); -const Organization = require('../../models/Organization'); -const userExists = require('../../helper_functions/userExists'); - -const uploadImage = require('../../helper_functions/uploadImage'); - -const createOrganization = async (parent, args, context) => { - //gets user in token - to be used later on - let userFound = await userExists(context.userId); - - //Upload file - let uploadImageObj; - if (args.file) { - uploadImageObj = await uploadImage(args.file, null); - } - - let newOrganization = new Organization({ - ...args.data, - image: uploadImageObj - ? uploadImageObj.imageAlreadyInDbPath - ? uploadImageObj.imageAlreadyInDbPath - : uploadImageObj.newImagePath - : null, - creator: userFound, - admins: [userFound], - members: [userFound], - }); - await newOrganization.save(); - - await User.findOneAndUpdate( - { _id: userFound.id }, - { - $set: { - joinedOrganizations: [ - ...userFound._doc.joinedOrganizations, - newOrganization, - ], - createdOrganizations: [ - ...userFound._doc.createdOrganizations, - newOrganization, - ], - adminFor: [...userFound._doc.adminFor, newOrganization], - }, - } - ); - - return newOrganization.toObject(); -}; - -module.exports = createOrganization; diff --git a/lib/resolvers/organization_mutations/removeOrganization.js b/lib/resolvers/organization_mutations/removeOrganization.js deleted file mode 100644 index c27a9dc04b..0000000000 --- a/lib/resolvers/organization_mutations/removeOrganization.js +++ /dev/null @@ -1,113 +0,0 @@ -const User = require('../../models/User'); -const MembershipRequest = require('../../models/MembershipRequest'); -const Comment = require('../../models/Comment'); -const Post = require('../../models/Post'); -const Organization = require('../../models/Organization'); -const creatorCheck = require('../functions/creatorCheck'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, - - IN_PRODUCTION, -} = require('../../../constants'); - -const removeOrganizaiton = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - // checks to see if organization exists - const org = await Organization.findOne({ _id: args.id }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - // check if the user is the creator - creatorCheck(context, org); - - //remove posts related to this organization - org.posts.forEach(async (postId) => { - await Post.findByIdAndDelete(postId); - await Comment.deleteMany({ post: postId }); - }); - - // remove organization from the user's created organization field - user.overwrite({ - ...user._doc, - createdOrganizations: user._doc.createdOrganizations.filter( - (organizationId) => organizationId.toString() !== org.id - ), - }); - await user.save(); - - // Remove organization from each member's joined organizations field - for (let memberId of org.members) { - const member = await User.findById(memberId); - member.joinedOrganizations = member.joinedOrganizations.filter( - (organizationId) => organizationId.toString() !== org.id - ); - await member.save(); - } - - // Remove organization from all member's adminFor field - for (let adminId of org.admins) { - const admin = await User.findById(adminId); - admin.adminFor = admin.joinedOrganizations.filter( - (organizationId) => organizationId.toString() !== org.id - ); - await admin.save(); - } - - // remove membership requests related to this organization - for (let membershipRequestId of org.membershipRequests) { - const membershipRequest = await MembershipRequest.findByIdAndDelete( - membershipRequestId - ); - const requester = await User.findById(membershipRequest.user); - requester.membershipRequests = requester.membershipRequests.filter( - (RequestId) => RequestId.toString() !== membershipRequestId.toString() - ); - await requester.save(); - } - - // remove organization from all blocked user's organizationsBlockedBy field - for (let blockedId of org.blockedUsers) { - const blocked = await User.findById(blockedId); - blocked.organizationsBlockedBy = blocked.organizationsBlockedBy.filter( - (organizationId) => organizationId.toString() !== org.id - ); - await blocked.save(); - } - - // delete organzation - await Organization.deleteOne({ _id: args.id }); - - return { - ...user._doc, - password: null, - }; -}; - -module.exports = removeOrganizaiton; diff --git a/lib/resolvers/organization_mutations/updateOrganization.js b/lib/resolvers/organization_mutations/updateOrganization.js deleted file mode 100644 index fbc678ab90..0000000000 --- a/lib/resolvers/organization_mutations/updateOrganization.js +++ /dev/null @@ -1,39 +0,0 @@ -const Organization = require('../../models/Organization'); -const adminCheck = require('../functions/adminCheck'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, -} = require('../../../constants'); - -const updateOrganization = async (parent, args, context) => { - //checks to see if organization exists - let org = await Organization.findOne({ _id: args.id }); - if (!org) { - throw new NotFoundError( - !IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - - //check if the user is an admin - adminCheck(context, org); - - //UPDATE ORGANIZATION - org.overwrite({ - ...org._doc, - ...args.data, - }); - await org.save(); - - return org; -}; - -module.exports = updateOrganization; diff --git a/lib/resolvers/organization_query/organizations.js b/lib/resolvers/organization_query/organizations.js deleted file mode 100644 index 7fd74e0f36..0000000000 --- a/lib/resolvers/organization_query/organizations.js +++ /dev/null @@ -1,59 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const Organization = require('../../models/Organization'); - -// THE UNIT FUNCTION TO SORT THE RESULTS OF THE OUTPUT ARRAY -// -// FUNCTION AIM: -// IF USER WANTS THE SORTING THEN FUNCTION RETURN THE RESPONSE TO DO SORTING IN DATABASE -// -const sortingFilter = (args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'name_ASC') { - sort = { name: 1 }; - } else if (args.orderBy === 'name_DESC') { - sort = { name: -1 }; - } else if (args.orderBy === 'description_ASC') { - sort = { description: 1 }; - } else if (args.orderBy === 'description_DESC') { - sort = { description: -1 }; - } else if (args.orderBy === 'apiUrl_ASC') { - sort = { apiUrl: 1 }; - } else { - sort = { apiUrl: -1 }; - } - } - - return sort; -}; - -module.exports = async (parent, args) => { - const sort = sortingFilter(args); - - if (args.id) { - const organizationFound = await Organization.find({ - _id: args.id, - }).sort(sort); - if (!organizationFound[0]) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Organization not found' - : requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - return organizationFound; - } else { - return await Organization.find().sort(sort).limit(100); - } -}; diff --git a/lib/resolvers/organization_query/organizations_pagination.js b/lib/resolvers/organization_query/organizations_pagination.js deleted file mode 100644 index dc02244b03..0000000000 --- a/lib/resolvers/organization_query/organizations_pagination.js +++ /dev/null @@ -1,237 +0,0 @@ -const Organization = require('../../models/Organization'); - -const organizationsConnection = async (parent, args) => { - var inputArg = {}; - var isSortingExecuted = args.orderBy !== null; - const filterParam = args.where; - - if (filterParam) { - //Returns provided id organizations - if (filterParam.id) { - inputArg = { - ...inputArg, - _id: filterParam.id, - }; - } - - //Returns all organizations other than provided id - if (filterParam.id_not) { - inputArg = { - ...inputArg, - _id: { $ne: filterParam.id_not }, - }; - } - - //Return organizations with id in the provided list - if (filterParam.id_in) { - inputArg = { - ...inputArg, - _id: { $in: filterParam.id_in }, - }; - } - - //Returns organizations not included in provided id list - if (filterParam.id_not_in) { - inputArg = { - ...inputArg, - _id: { $nin: filterParam.id_not_in }, - }; - } - - //Returns provided name organization - if (filterParam.name) { - inputArg = { - ...inputArg, - name: filterParam.name, - }; - } - - //Returns organizations with not that name - if (filterParam.name_not) { - inputArg = { - ...inputArg, - name: { $ne: filterParam.name_not }, - }; - } - - //Return organizations with the given list name - if (filterParam.name_in) { - inputArg = { - ...inputArg, - name: { $in: filterParam.name_in }, - }; - } - - //Returns organizations with name not in the provided list - if (filterParam.name_not_in) { - inputArg = { - ...inputArg, - name: { $nin: filterParam.name_not_in }, - }; - } - - //Returns organizations with name containing provided string - if (filterParam.name_contains) { - inputArg = { - ...inputArg, - name: { $regex: filterParam.name_contains, $options: 'i' }, - }; - } - - //Returns organizations with name starts with that provided string - if (filterParam.name_starts_with) { - const regexp = new RegExp('^' + filterParam.name_starts_with); - inputArg = { - ...inputArg, - name: regexp, - }; - } - - //Returns description organizations - if (filterParam.description) { - inputArg = { - ...inputArg, - description: filterParam.description, - }; - } - - //Returns organizations with not that description - if (filterParam.description_not) { - inputArg = { - ...inputArg, - description: { $ne: filterParam.description_not }, - }; - } - - //Return organizations with description in provided list - if (filterParam.description_in) { - inputArg = { - ...inputArg, - description: { $in: filterParam.description_in }, - }; - } - - //Return organizations with description not in provided list - if (filterParam.description_not_in) { - inputArg = { - ...inputArg, - description: { $nin: filterParam.description_not_in }, - }; - } - - //Return organizations with description should containing provided string - if (filterParam.description_contains) { - inputArg = { - ...inputArg, - description: { - $regex: filterParam.description_contains, - $options: 'i', - }, - }; - } - - //Returns organizations with description starting with provided string - if (filterParam.description_starts_with) { - const regexp = new RegExp('^' + filterParam.description_starts_with); - inputArg = { - ...inputArg, - description: regexp, - }; - } - - //Returns provided apiUrl organizations - if (filterParam.apiUrl) { - inputArg = { - ...inputArg, - apiUrl: filterParam.apiUrl, - }; - } - - //Returns organizations with not that provided apiUrl - if (filterParam.apiUrl_not) { - inputArg = { - ...inputArg, - apiUrl: { $ne: filterParam.apiUrl_not }, - }; - } - - //organizations apiUrl falls in provided list - if (filterParam.apiUrl_in) { - inputArg = { - ...inputArg, - apiUrl: { $in: filterParam.apiUrl_in }, - }; - } - - //Return organizations apiUrl not falls in the list - if (filterParam.apiUrl_not_in) { - inputArg = { - ...inputArg, - apiUrl: { $nin: filterParam.apiUrl_not_in }, - }; - } - - //Return organizations with apiUrl containing provided string - if (filterParam.apiUrl_contains) { - inputArg = { - ...inputArg, - apiUrl: { $regex: filterParam.apiUrl_contains, $options: 'i' }, - }; - } - - //Returns organizations with apiUrl starts with provided string - if (filterParam.apiUrl_starts_with) { - const regexp = new RegExp('^' + filterParam.apiUrl_starts_with); - inputArg = { - ...inputArg, - apiUrl: regexp, - }; - } - - //Returns organizations with provided visibleInSearch condition - if (filterParam.visibleInSearch !== undefined) { - inputArg = { - ...inputArg, - visibleInSearch: filterParam.visibleInSearch, - }; - } - - //Returns organizations with provided isPublic condition - if (filterParam.isPublic !== undefined) { - inputArg = { - ...inputArg, - isPublic: filterParam.isPublic, - }; - } - } - - var sort = {}; - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'name_ASC') { - sort = { name: 1 }; - } else if (args.orderBy === 'name_DESC') { - sort = { name: -1 }; - } else if (args.orderBy === 'description_ASC') { - sort = { description: 1 }; - } else if (args.orderBy === 'description_DESC') { - sort = { description: -1 }; - } else if (args.orderBy === 'apiUrl_ASC') { - sort = { apiUrl: 1 }; - } else { - sort = { apiUrl: -1 }; - } - } - - const organizationFound = await Organization.find(inputArg) - .sort(sort) - .limit(args.first) - .skip(args.skip); - - return organizationFound; -}; - -module.exports = organizationsConnection; diff --git a/lib/resolvers/plugin_mutations/createPlugin.js b/lib/resolvers/plugin_mutations/createPlugin.js deleted file mode 100644 index 37f4c6a072..0000000000 --- a/lib/resolvers/plugin_mutations/createPlugin.js +++ /dev/null @@ -1,24 +0,0 @@ -const Plugin = require('../../models/Plugin'); -/** - * @name createPlugin creates a Plugin and return the same - * @description creates a document of Plugin type and stores it in database - * @param {any} parent parent of current request - * @param {object} args payload provided with the request - * @param {any} context context of entire application - */ -// eslint-disable-next-line no-unused-vars -module.exports = async (parent, args, context) => { - //create MongoDB document - let plugin = new Plugin({ - pluginName: args.pluginName, - pluginCreatedBy: args.pluginCreatedBy, - pluginDesc: args.pluginDesc, - pluginInstallStatus: args.pluginInstallStatus, - installedOrgs: args.installedOrgs, - }); - //store the plugin - plugin = await Plugin.save(); - return { - ...plugin._doc, - }; -}; diff --git a/lib/resolvers/plugin_mutations/updatePluginInstalledOrgs.js b/lib/resolvers/plugin_mutations/updatePluginInstalledOrgs.js deleted file mode 100644 index ac93a35e98..0000000000 --- a/lib/resolvers/plugin_mutations/updatePluginInstalledOrgs.js +++ /dev/null @@ -1,47 +0,0 @@ -const Plugin = require('../../models/Plugin'); -/** - * @name updatePluginInstalledOrgs - * @description updates the installedOrgs list of the specific plugin and adds or removes the current orgId from the list. - * @param {any} parent parent of current request - * @param {object} args payload provided with the request - * @param {any} context context of entire application - */ -// eslint-disable-next-line no-unused-vars -module.exports = async (parent, args, context) => { - let plug = await Plugin.findById(args.id); - const plugOrgList = plug?.installedOrgs; - const isDuplicate = plugOrgList?.includes(args.orgId); - // remove the entry if duplicate - if (isDuplicate) { - // eslint-disable-next-line no-unused-vars - const result = await Plugin.findByIdAndUpdate( - args.id, - { $pull: { installedOrgs: args.orgId } }, - { new: true }, - (err, res) => { - if (err) { - console.log(err); - } else { - console.log('Updated Plugin with installed orgs : ', res); - } - } - ); - } else { - // eslint-disable-next-line no-unused-vars - const result = await Plugin.findByIdAndUpdate( - args.id, - { $push: { installedOrgs: args.orgId } }, - { new: true }, - (err, res) => { - if (err) { - console.log(err); - } else { - console.log('Updated Plugin with installed orgs : ', res); - } - } - ); - } - - plug = await Plugin.findById(args.id); - return plug; -}; diff --git a/lib/resolvers/plugin_mutations/updatePluginStatus.js b/lib/resolvers/plugin_mutations/updatePluginStatus.js deleted file mode 100644 index 6151913241..0000000000 --- a/lib/resolvers/plugin_mutations/updatePluginStatus.js +++ /dev/null @@ -1,27 +0,0 @@ -const Plugin = require('../../models/Plugin'); -/** - * @name updatePluginStatus - * @description toggles the installStatus of the plugin - * @param {any} parent parent of current request - * @param {object} args payload provided with the request - * @param {any} context context of entire application - */ -// eslint-disable-next-line no-unused-vars -module.exports = async (parent, args, context) => { - console.log('Argment s ', args); - // eslint-disable-next-line no-unused-vars - const result = await Plugin.findByIdAndUpdate( - args.id, - { pluginInstallStatus: args.status }, - { new: true }, - (err, res) => { - if (err) { - console.log(err); - } else { - console.log('Updated Plugin : ', res); - } - } - ); - const plug = await Plugin.findById(args.id); - return plug; -}; diff --git a/lib/resolvers/plugin_query/getPlugins.js b/lib/resolvers/plugin_query/getPlugins.js deleted file mode 100644 index c4c0245cf1..0000000000 --- a/lib/resolvers/plugin_query/getPlugins.js +++ /dev/null @@ -1,8 +0,0 @@ -const Plugin = require('../../models/Plugin'); -/** - * @name getPlugins a GraphQL Query - * @description returns list of plugin from database - */ -module.exports = async () => { - return await Plugin.find(); -}; diff --git a/lib/resolvers/post_mutations/createComment.js b/lib/resolvers/post_mutations/createComment.js deleted file mode 100644 index d730433c67..0000000000 --- a/lib/resolvers/post_mutations/createComment.js +++ /dev/null @@ -1,42 +0,0 @@ -const User = require('../../models/User'); -const Comment = require('../../models/Comment'); -const Post = require('../../models/Post'); - -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - // gets user in token - to be used later on - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - let newComment = new Comment({ - ...args.data, - creator: context.userId, - post: args.postId, - }); - - await Post.updateOne( - { _id: args.postId }, - { - $push: { - comments: newComment, - }, - $inc: { - commentCount: 1, - }, - } - ); - - newComment = await newComment.save(); - - return { - ...newComment._doc, - }; -}; diff --git a/lib/resolvers/post_mutations/createPost.js b/lib/resolvers/post_mutations/createPost.js deleted file mode 100644 index b75b223d23..0000000000 --- a/lib/resolvers/post_mutations/createPost.js +++ /dev/null @@ -1,50 +0,0 @@ -const User = require('../../models/User'); -const Post = require('../../models/Post'); -const Organization = require('../../models/Organization'); - -const uploadImage = require('../../helper_functions/uploadImage'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - // gets user in token - to be used later on - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const organization = await Organization.findOne({ - _id: args.data.organizationId, - }); - if (!organization) { - throw new NotFoundError( - requestContext.translate('organization.notFound'), - 'organization.notFound', - 'organization' - ); - } - - let uploadImageObj; - if (args.file) { - uploadImageObj = await uploadImage(args.file, ''); - } - // creates new Post - let newPost = new Post({ - ...args.data, - creator: context.userId, - organization: args.data.organizationId, - imageUrl: args.file ? uploadImageObj.newImagePath : '', - }); - - newPost = await newPost.save(); - - // add creator - - return { - ...newPost._doc, - }; -}; diff --git a/lib/resolvers/post_mutations/likeComment.js b/lib/resolvers/post_mutations/likeComment.js deleted file mode 100644 index 74346036b7..0000000000 --- a/lib/resolvers/post_mutations/likeComment.js +++ /dev/null @@ -1,36 +0,0 @@ -const User = require('../../models/User'); -const Comment = require('../../models/Comment'); - -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const likeComment = async (parent, args, context) => { - const user = await User.findById(context.userId); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - let comment = await Comment.findById(args.id); - if (!comment) { - throw new NotFoundError( - requestContext.translate('comment.notFound'), - 'comment.notFound', - 'comment' - ); - } - if (!comment.likedBy.includes(context.userId)) { - let newComment = await Comment.findByIdAndUpdate( - args.id, - { $push: { likedBy: user }, $inc: { likeCount: 1 } }, - { new: true } - ); - return newComment; - } - return comment; -}; - -module.exports = likeComment; diff --git a/lib/resolvers/post_mutations/likePost.js b/lib/resolvers/post_mutations/likePost.js deleted file mode 100644 index 6830a6a657..0000000000 --- a/lib/resolvers/post_mutations/likePost.js +++ /dev/null @@ -1,44 +0,0 @@ -const User = require('../../models/User'); -const Post = require('../../models/Post'); - -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const likePost = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const post = await Post.findOne({ _id: args.id }); - if (!post) { - throw new NotFoundError( - requestContext.translate('post.notFound'), - 'post.notFound', - 'post' - ); - } - - if (!post.likedBy.includes(context.userId)) { - const newPost = await Post.findOneAndUpdate( - { _id: args.id }, - { - $push: { - likedBy: user, - }, - $inc: { - likeCount: 1, - }, - }, - { new: true } - ); - return newPost; - } - return post; -}; - -module.exports = likePost; diff --git a/lib/resolvers/post_mutations/removeComment.js b/lib/resolvers/post_mutations/removeComment.js deleted file mode 100644 index a75b40f082..0000000000 --- a/lib/resolvers/post_mutations/removeComment.js +++ /dev/null @@ -1,51 +0,0 @@ -const User = require('../../models/User'); -const Comment = require('../../models/Comment'); -const Post = require('../../models/Post'); - -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const removeComment = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const comment = await Comment.findOne({ _id: args.id }); - if (!comment) { - throw new NotFoundError( - requestContext.translate('comment.notFound'), - 'comment.notFound', - 'comment' - ); - } - - if (!(comment.creator !== context.userId)) { - throw new UnauthorizedError( - requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - await Post.updateOne( - { _id: comment.post }, - { - $pull: { - comments: args.id, - }, - $inc: { - commentCount: -1, - }, - } - ); - - await Comment.deleteOne({ _id: args.id }); - return comment; -}; - -module.exports = removeComment; diff --git a/lib/resolvers/post_mutations/removePost.js b/lib/resolvers/post_mutations/removePost.js deleted file mode 100644 index c1e3ee63e6..0000000000 --- a/lib/resolvers/post_mutations/removePost.js +++ /dev/null @@ -1,38 +0,0 @@ -const User = require('../../models/User'); -const Post = require('../../models/Post'); - -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const removePost = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const post = await Post.findOne({ _id: args.id }); - if (!post) { - throw new NotFoundError( - requestContext.translate('post.notFound'), - 'post.notFound', - 'post' - ); - } - - if (!(post.creator !== context.userId)) { - throw new UnauthorizedError( - requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - await Post.deleteOne({ _id: args.id }); - return post; -}; - -module.exports = removePost; diff --git a/lib/resolvers/post_mutations/unlikeComment.js b/lib/resolvers/post_mutations/unlikeComment.js deleted file mode 100644 index 2492fd1023..0000000000 --- a/lib/resolvers/post_mutations/unlikeComment.js +++ /dev/null @@ -1,36 +0,0 @@ -const User = require('../../models/User'); -const Comment = require('../../models/Comment'); - -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const unlikeComment = async (parent, args, context) => { - const user = await User.findById(context.userId); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - let comment = await Comment.findById(args.id); - if (!comment) { - throw new NotFoundError( - requestContext.translate('comment.notFound'), - 'comment.notFound', - 'comment' - ); - } - if (comment.likedBy.includes(context.userId)) { - let newComment = await Comment.findByIdAndUpdate( - args.id, - { $pull: { likedBy: context.userId }, $inc: { likeCount: -1 } }, - { new: true } - ); - return newComment; - } - return comment; -}; - -module.exports = unlikeComment; diff --git a/lib/resolvers/post_mutations/unlikePost.js b/lib/resolvers/post_mutations/unlikePost.js deleted file mode 100644 index 54d1299790..0000000000 --- a/lib/resolvers/post_mutations/unlikePost.js +++ /dev/null @@ -1,44 +0,0 @@ -const User = require('../../models/User'); -const Post = require('../../models/Post'); - -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const unlikePost = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const post = await Post.findOne({ _id: args.id }); - if (!post) { - throw new NotFoundError( - requestContext.translate('post.notFound'), - 'post.notFound', - 'post' - ); - } - if (post.likedBy.includes(context.userId)) { - const newPost = await Post.findOneAndUpdate( - { _id: args.id }, - { - $pull: { - likedBy: context.userId, - }, - $inc: { - commentCount: -1, - }, - }, - { new: true } - ); - - return newPost; - } - return post; -}; - -module.exports = unlikePost; diff --git a/lib/resolvers/post_organization_query/organization_post_pagination.js b/lib/resolvers/post_organization_query/organization_post_pagination.js deleted file mode 100644 index 511c8426a5..0000000000 --- a/lib/resolvers/post_organization_query/organization_post_pagination.js +++ /dev/null @@ -1,314 +0,0 @@ -const { ValidationError } = require('errors'); -const Post = require('../../models/Post'); -const requestContext = require('talawa-request-context'); - -const postsByOrganizationConnection = async (parent, args) => { - var sort = {}; - var inputArg = {}; - - const filterParam = args.where; - var isSortingExecuted = args.orderBy !== null; - - // Sorting List of data - if (isSortingExecuted) { - sort = sortingData(args.orderBy); - } - - // Filtering List of data - if (filterParam) { - inputArg = filteringData(filterParam); - } - - // Pagination based Options - var options = {}; - if (args.first) { - if (args.skip === null) { - throw new ValidationError( - requestContext.translate('parameter.missing'), - 'parameter.missing', - 'parameter' - ); - } - - options = { - lean: true, - sort: sort, - pagination: true, - page: args.skip, - limit: args.first, - populate: ['organization', 'likedBy', 'comments'], - }; - } else { - options = { - sort: sort, - pagination: false, - populate: ['organization', 'likedBy', 'comments'], - }; - } - - // Set of posts - const postsmodel = await Post.paginate( - { - organization: args.id, - ...inputArg, - }, - options - ); - - const posts = postsmodel.docs.map((post) => { - post.likeCount = post.likedBy.length || 0; - post.commentCount = post.comments.length || 0; - return post; - }); - - return { - pageInfo: { - hasNextPage: postsmodel.hasNextPage, - hasPreviousPage: postsmodel.hasPrevPage, - totalPages: postsmodel.totalPages, - nextPageNo: postsmodel.nextPage, - prevPageNo: postsmodel.prevPage, - currPageNo: postsmodel.page, - }, - edges: posts, - aggregate: { - count: postsmodel.totalDocs, - }, - }; -}; - -const filteringData = (filterParam) => { - var inputArg = {}; - if (filterParam.id) { - inputArg = { - ...inputArg, - _id: filterParam.id, - }; - } - - //Returns all Posts other than provided id - if (filterParam.id_not) { - inputArg = { - ...inputArg, - _id: { - $ne: filterParam.id_not, - }, - }; - } - - //Return Posts with id in the provided list - if (filterParam.id_in) { - inputArg = { - ...inputArg, - _id: { - $in: filterParam.id_in, - }, - }; - } - - //Returns Posts not included in provided id list - if (filterParam.id_not_in) { - inputArg = { - ...inputArg, - _id: { - $nin: filterParam.id_not_in, - }, - }; - } - - //Returns provided text Posts - if (filterParam.text) { - inputArg = { - ...inputArg, - text: filterParam.text, - }; - } - - //Returns Posts with not the provided text - if (filterParam.text_not) { - inputArg = { - ...inputArg, - text: { - $ne: filterParam.text_not, - }, - }; - } - - //Return Posts with the given list text - if (filterParam.text_in) { - inputArg = { - ...inputArg, - text: { - $in: filterParam.text_in, - }, - }; - } - - //Returns Posts with text not in the provided list - if (filterParam.text_not_in) { - inputArg = { - ...inputArg, - text: { - $nin: filterParam.text_not_in, - }, - }; - } - - //Returns Posts with text containing provided string - if (filterParam.text_contains) { - inputArg = { - ...inputArg, - text: { - $regex: filterParam.text_contains, - $options: 'i', - }, - }; - } - - //Returns Posts with text starts with that provided string - if (filterParam.text_starts_with) { - const regexp = new RegExp('^' + filterParam.text_starts_with); - inputArg = { - ...inputArg, - text: regexp, - }; - } - - //Returns provided title Posts - if (filterParam.title) { - inputArg = { - ...inputArg, - title: filterParam.title, - }; - } - - //Returns Posts with not that title - if (filterParam.title_not) { - inputArg = { - ...inputArg, - title: { - $ne: filterParam.title_not, - }, - }; - } - - //Return Posts with the given list title - if (filterParam.title_in) { - inputArg = { - ...inputArg, - title: { - $in: filterParam.title_in, - }, - }; - } - - //Returns Posts with title not in the provided list - if (filterParam.title_not_in) { - inputArg = { - ...inputArg, - title: { - $nin: filterParam.title_not_in, - }, - }; - } - - //Returns Posts with title containing provided string - if (filterParam.title_contains) { - inputArg = { - ...inputArg, - title: { - $regex: filterParam.title_contains, - $options: 'i', - }, - }; - } - - //Returns Posts with title starts with that provided string - if (filterParam.title_starts_with) { - const regexp = new RegExp('^' + filterParam.title_starts_with); - inputArg = { - ...inputArg, - title: regexp, - }; - } - - return inputArg; -}; - -const sortingData = (orderBy) => { - var sort = {}; - var isSortingExecuted = orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (orderBy === 'id_ASC') { - sort = { - _id: 1, - }; - } else if (orderBy === 'id_DESC') { - sort = { - _id: -1, - }; - } else if (orderBy === 'text_ASC') { - sort = { - text: 1, - }; - } else if (orderBy === 'text_DESC') { - sort = { - text: -1, - }; - } else if (orderBy === 'title_ASC') { - sort = { - title: 1, - }; - } else if (orderBy === 'title_DESC') { - sort = { - title: -1, - }; - } else if (orderBy === 'createdAt_ASC') { - sort = { - createdAt: 1, - }; - } else if (orderBy === 'createdAt_DESC') { - sort = { - createdAt: -1, - }; - } else if (orderBy === 'imageUrl_ASC') { - sort = { - imageUrl: 1, - }; - } else if (orderBy === 'imageUrl_DESC') { - sort = { - imageUrl: -1, - }; - } else if (orderBy === 'videoUrl_ASC') { - sort = { - videoUrl: 1, - }; - } else if (orderBy === 'videoUrl_DESC') { - sort = { - videoUrl: -1, - }; - } else if (orderBy === 'likeCount_ASC') { - sort = { - likeCount: 1, - }; - } else if (orderBy === 'likeCount_DESC') { - sort = { - likeCount: -1, - }; - } else if (orderBy === 'commentCount_ASC') { - sort = { - commentCount: 1, - }; - } else { - sort = { - commentCount: -1, - }; - } - } - - return sort; -}; - -module.exports = postsByOrganizationConnection; diff --git a/lib/resolvers/post_query/comments.js b/lib/resolvers/post_query/comments.js deleted file mode 100644 index ab56a439b6..0000000000 --- a/lib/resolvers/post_query/comments.js +++ /dev/null @@ -1,19 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const Comment = require('../../models/Comment'); - -module.exports = async () => { - const commentFound = await Comment.find() - .populate('creator', '-password') - .populate('post') - .populate('likedBy'); - if (!commentFound) { - throw new NotFoundError( - requestContext.translate('comment.notFound'), - 'comment.notFound', - 'comment' - ); - } - return commentFound; -}; diff --git a/lib/resolvers/post_query/commentsByPost.js b/lib/resolvers/post_query/commentsByPost.js deleted file mode 100644 index 4a6a51107a..0000000000 --- a/lib/resolvers/post_query/commentsByPost.js +++ /dev/null @@ -1,80 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const Comment = require('../../models/Comment'); -const Organization = require('../../models/Organization'); - -const { - COMMENT_NOT_FOUND, - COMMENT_NOT_FOUND_MESSAGE, - COMMENT_NOT_FOUND_CODE, - COMMENT_NOT_FOUND_PARAM, - - POST_NOT_FOUND, - POST_NOT_FOUND_MESSAGE, - POST_NOT_FOUND_CODE, - POST_NOT_FOUND_PARAM, - - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - - ORGANIZATION_NOT_FOUND, - ORGANIZATION_NOT_FOUND_MESSAGE, - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM, - - IN_PRODUCTION, -} = require('../../../constants'); - -module.exports = async (parent, args) => { - const commentFound = await Comment.find({ post: args.id }) - .populate('creator', '-password') - .populate('post') - .populate('likedBy'); - //comment does not exist - if (!commentFound.length) { - throw new NotFoundError( - process.env.NODE_ENV !== IN_PRODUCTION - ? COMMENT_NOT_FOUND - : requestContext.translate(COMMENT_NOT_FOUND_MESSAGE), - COMMENT_NOT_FOUND_CODE, - COMMENT_NOT_FOUND_PARAM - ); - } - //user does not exist - if (!commentFound[0].creator) { - throw new NotFoundError( - process.env.NODE_ENV !== IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - //post does not exist - if (!commentFound[0].post) { - throw new NotFoundError( - process.env.NODE_ENV !== IN_PRODUCTION - ? POST_NOT_FOUND - : requestContext.translate(POST_NOT_FOUND_MESSAGE), - POST_NOT_FOUND_CODE, - POST_NOT_FOUND_PARAM - ); - } - //organization does not exist - const org = await Organization.find({ - _id: commentFound[0].post.organization, - }); - if (!org.length) { - throw new NotFoundError( - process.env.NODE_ENV !== IN_PRODUCTION - ? ORGANIZATION_NOT_FOUND - : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), - ORGANIZATION_NOT_FOUND_CODE, - ORGANIZATION_NOT_FOUND_PARAM - ); - } - return commentFound; -}; diff --git a/lib/resolvers/post_query/post.js b/lib/resolvers/post_query/post.js deleted file mode 100644 index b86692e193..0000000000 --- a/lib/resolvers/post_query/post.js +++ /dev/null @@ -1,31 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const Post = require('../../models/Post'); - -module.exports = async (parent, args) => { - const postFound = await Post.findOne({ - _id: args.id, - }) - .populate('organization') - .populate({ - path: 'comments', - populate: { - path: 'creator', - }, - }) - .populate('likedBy') - .populate('creator', '-password'); - if (!postFound) { - throw new NotFoundError( - process.env.NODE_ENV !== 'production' - ? 'Post not found' - : requestContext.translate('post.notFound'), - 'post.notFound', - 'post' - ); - } - postFound.likeCount = postFound.likedBy.length || 0; - postFound.commentCount = postFound.comments.length || 0; - return postFound; -}; diff --git a/lib/resolvers/post_query/posts.js b/lib/resolvers/post_query/posts.js deleted file mode 100644 index ab76a8a3fa..0000000000 --- a/lib/resolvers/post_query/posts.js +++ /dev/null @@ -1,60 +0,0 @@ -const Post = require('../../models/Post'); - -module.exports = async (parent, args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'text_ASC') { - sort = { text: 1 }; - } else if (args.orderBy === 'text_DESC') { - sort = { text: -1 }; - } else if (args.orderBy === 'title_ASC') { - sort = { title: 1 }; - } else if (args.orderBy === 'title_DESC') { - sort = { title: -1 }; - } else if (args.orderBy === 'createdAt_ASC') { - sort = { createdAt: 1 }; - } else if (args.orderBy === 'createdAt_DESC') { - sort = { createdAt: -1 }; - } else if (args.orderBy === 'imageUrl_ASC') { - sort = { imageUrl: 1 }; - } else if (args.orderBy === 'imageUrl_DESC') { - sort = { imageUrl: -1 }; - } else if (args.orderBy === 'videoUrl_ASC') { - sort = { videoUrl: 1 }; - } else if (args.orderBy === 'videoUrl_DESC') { - sort = { videoUrl: -1 }; - } else if (args.orderBy === 'likeCount_ASC') { - sort = { likeCount: 1 }; - } else if (args.orderBy === 'likeCount_DESC') { - sort = { likeCount: -1 }; - } else if (args.orderBy === 'commentCount_ASC') { - sort = { commentCount: 1 }; - } else { - sort = { commentCount: -1 }; - } - } - const p = await Post.find() - .sort(sort) - .populate('organization') - .populate('likedBy') - .populate({ - path: 'comments', - populate: { - path: 'creator', - }, - }) - .populate('creator', '-password'); - const posts = p.map((post) => { - post.likeCount = post.likedBy.length || 0; - post.commentCount = post.comments.length || 0; - return post; - }); - return posts; -}; diff --git a/lib/resolvers/post_query/postsByOrganization.js b/lib/resolvers/post_query/postsByOrganization.js deleted file mode 100644 index 6351e9eb32..0000000000 --- a/lib/resolvers/post_query/postsByOrganization.js +++ /dev/null @@ -1,57 +0,0 @@ -const Post = require('../../models/Post'); - -module.exports = async (parent, args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'text_ASC') { - sort = { text: 1 }; - } else if (args.orderBy === 'text_DESC') { - sort = { text: -1 }; - } else if (args.orderBy === 'title_ASC') { - sort = { title: 1 }; - } else if (args.orderBy === 'title_DESC') { - sort = { title: -1 }; - } else if (args.orderBy === 'createdAt_ASC') { - sort = { createdAt: 1 }; - } else if (args.orderBy === 'createdAt_DESC') { - sort = { createdAt: -1 }; - } else if (args.orderBy === 'imageUrl_ASC') { - sort = { imageUrl: 1 }; - } else if (args.orderBy === 'imageUrl_DESC') { - sort = { imageUrl: -1 }; - } else if (args.orderBy === 'videoUrl_ASC') { - sort = { videoUrl: 1 }; - } else if (args.orderBy === 'videoUrl_DESC') { - sort = { videoUrl: -1 }; - } else if (args.orderBy === 'likeCount_ASC') { - sort = { likeCount: 1 }; - } else if (args.orderBy === 'likeCount_DESC') { - sort = { likeCount: -1 }; - } else if (args.orderBy === 'commentCount_ASC') { - sort = { commentCount: 1 }; - } else { - sort = { commentCount: -1 }; - } - } - - return Post.find({ - organization: args.id, - }) - .sort(sort) - .populate('organization') - .populate('likedBy') - .populate({ - path: 'comments', - populate: { - path: 'creator', - }, - }) - .populate('creator', '-password'); -}; diff --git a/lib/resolvers/project_task_mutations/createTask.js b/lib/resolvers/project_task_mutations/createTask.js deleted file mode 100644 index c961758d12..0000000000 --- a/lib/resolvers/project_task_mutations/createTask.js +++ /dev/null @@ -1,64 +0,0 @@ -const User = require('../../models/User'); -const Task = require('../../models/Task'); -const Event = require('../../models/Event'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, - EVENT_NOT_FOUND, - EVENT_NOT_FOUND_MESSAGE, - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM, -} = require('../../../constants'); -const createTask = async (parent, args, context) => { - // gets user in token - to be used later on - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - const eventFound = await Event.findOne({ - _id: args.eventId, - }); - if (!eventFound) { - throw new NotFoundError( - !IN_PRODUCTION - ? EVENT_NOT_FOUND - : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), - EVENT_NOT_FOUND_CODE, - EVENT_NOT_FOUND_PARAM - ); - } - - const task = new Task({ - ...args.data, - event: eventFound, - creator: user, - }); - await task.save(); - - await Event.findOneAndUpdate( - { _id: args.eventId }, - { - $push: { - tasks: task, - }, - }, - { new: true } - ); - return { - ...task._doc, - }; -}; - -module.exports = createTask; diff --git a/lib/resolvers/project_task_mutations/removeTask.js b/lib/resolvers/project_task_mutations/removeTask.js deleted file mode 100644 index 4fe1e880ae..0000000000 --- a/lib/resolvers/project_task_mutations/removeTask.js +++ /dev/null @@ -1,47 +0,0 @@ -const User = require('../../models/User'); -const Event = require('../../models/Event'); -const Task = require('../../models/Task'); -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const removeTask = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const foundTask = await Task.findOne({ _id: args.id }); - if (!foundTask) { - throw new NotFoundError( - requestContext.translate('task.notFound'), - 'task.notFound', - 'task' - ); - } - - if (!(foundTask.creator !== context.userId)) { - throw new UnauthorizedError( - requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - await Event.updateMany( - { id: foundTask.event }, - { - $pull: { - tasks: args.id, - }, - } - ); - - await Task.deleteOne({ _id: args.id }); - return foundTask; -}; - -module.exports = removeTask; diff --git a/lib/resolvers/project_task_mutations/updateTask.js b/lib/resolvers/project_task_mutations/updateTask.js deleted file mode 100644 index 2de780bf8d..0000000000 --- a/lib/resolvers/project_task_mutations/updateTask.js +++ /dev/null @@ -1,42 +0,0 @@ -const User = require('../../models/User'); -const Task = require('../../models/Task'); - -const { NotFoundError, UnauthorizedError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const updateTask = async (parent, args, context) => { - const user = await User.findOne({ _id: context.userId }); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const task = await Task.findOne({ _id: args.id }); - if (!task) { - throw new NotFoundError( - requestContext.translate('task.notFound'), - 'task.notFound', - 'task' - ); - } - - if (!(task.creator !== context.userId)) { - throw new UnauthorizedError( - requestContext.translate('user.notAuthorized'), - 'user.notAuthorized', - 'userAuthorization' - ); - } - - const newTask = await Task.findOneAndUpdate( - { _id: args.id }, - { ...args.data }, - { new: true } - ); - return newTask; -}; - -module.exports = updateTask; diff --git a/lib/resolvers/template.js b/lib/resolvers/template.js deleted file mode 100644 index ff6c288da1..0000000000 --- a/lib/resolvers/template.js +++ /dev/null @@ -1,2 +0,0 @@ -// eslint-disable-next-line no-unused-vars -module.exports = async (parent, args, context) => {}; diff --git a/lib/resolvers/user_image_mutations/add_user_image.js b/lib/resolvers/user_image_mutations/add_user_image.js deleted file mode 100644 index a7e1d72277..0000000000 --- a/lib/resolvers/user_image_mutations/add_user_image.js +++ /dev/null @@ -1,33 +0,0 @@ -const User = require('../../models/User'); -const uploadImageHelper = require('../../helper_functions/uploadImage'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const addUserImage = async (parent, args, context) => { - const user = await User.findById(context.userId); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const uploadImage = await uploadImageHelper(args.file, user.image); - - return await User.findOneAndUpdate( - { _id: user.id }, - { - $set: { - image: uploadImage.imageAlreadyInDbPath - ? uploadImage.imageAlreadyInDbPath - : uploadImage.newImagePath, - }, - }, - { - new: true, - } - ); -}; - -module.exports = addUserImage; diff --git a/lib/resolvers/user_image_mutations/remove_user_image.js b/lib/resolvers/user_image_mutations/remove_user_image.js deleted file mode 100644 index 4d96f5ab98..0000000000 --- a/lib/resolvers/user_image_mutations/remove_user_image.js +++ /dev/null @@ -1,40 +0,0 @@ -const User = require('../../models/User'); -const deleteImage = require('../../helper_functions/deleteImage'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -module.exports = async (parent, args, context) => { - const user = await User.findById(context.userId); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - if (!user.image) { - throw new NotFoundError( - requestContext.translate('user.profileImage.notFound'), - 'user.profileImage.notFound', - 'userProfileImage' - ); - } - - await deleteImage(user.image); - - const newUser = await User.findOneAndUpdate( - { - _id: user.id, - }, - { - $set: { - image: null, - }, - }, - { - new: true, - } - ); - return newUser; -}; diff --git a/lib/resolvers/user_mutations/blockForPlugin.js b/lib/resolvers/user_mutations/blockForPlugin.js deleted file mode 100644 index 658ca1d56a..0000000000 --- a/lib/resolvers/user_mutations/blockForPlugin.js +++ /dev/null @@ -1,36 +0,0 @@ -const { NotFoundError } = require('errors'); -const User = require('../../models/User'); -const userExists = require('../../helper_functions/userExists'); -const requestContext = require('talawa-request-context'); -const superAdminCheck = require('../../resolvers/functions/superAdminCheck'); - -module.exports = async (parent, args, context) => { - let userFound = await userExists(args.userId); - if (!userFound) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - const user = await User.findOne({ - _id: context.userId, - }); - - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - superAdminCheck(context, user); - userFound.overwrite({ - ...userFound._doc, - pluginCreationAllowed: !args.blockUser, - }); - - return userFound; -}; diff --git a/lib/resolvers/user_mutations/updateUserProfile.js b/lib/resolvers/user_mutations/updateUserProfile.js deleted file mode 100644 index f8b71b79a0..0000000000 --- a/lib/resolvers/user_mutations/updateUserProfile.js +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-disable no-useless-catch */ -const userExists = require('../../helper_functions/userExists'); -const User = require('../../models/User'); -const uploadImage = require('../../helper_functions/uploadImage'); -const { ConflictError, NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); - -const updateUserProfile = async (parent, args, context) => { - try { - //gets user in token - to be used later on - let userFound = await userExists(context.userId); - if (!userFound) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - if (args.data.email !== undefined) { - const emailTaken = await User.findOne({ - email: args.data.email.toLowerCase(), - }); - - if (emailTaken) { - throw new ConflictError( - requestContext.translate('email.alreadyExists'), - 'email.alreadyExists', - 'email' - ); - } - } - - // Upload file - let uploadImageObj; - if (args.file) { - uploadImageObj = await uploadImage(args.file, null); - } - - if (uploadImageObj) { - //UPDATE USER - userFound.overwrite({ - ...userFound._doc, - ...args.data, - image: uploadImageObj.imageAlreadyInDbPath - ? uploadImageObj.imageAlreadyInDbPath - : uploadImageObj.newImagePath, - }); - } else { - //UPDATE USER - userFound.overwrite({ - ...userFound._doc, - ...args.data, - }); - } - - await userFound.save(); - return userFound; - } catch (error) { - throw error; - } -}; - -module.exports = updateUserProfile; diff --git a/lib/resolvers/user_mutations/updateUserType.js b/lib/resolvers/user_mutations/updateUserType.js deleted file mode 100644 index 4866db59ed..0000000000 --- a/lib/resolvers/user_mutations/updateUserType.js +++ /dev/null @@ -1,19 +0,0 @@ -const User = require('../../models/User'); -const userExists = require('../../helper_functions/userExists'); -const { USER_NOT_AUTHORIZED } = require('../../../constants'); - -module.exports = async (parent, args, context) => { - const { id, userType } = args.data; - - const isSuperAdmin = await userExists(context.userId); - - if (isSuperAdmin.userType !== 'SUPERADMIN') { - throw new Error(USER_NOT_AUTHORIZED); - } - - await userExists(id); - - await User.findByIdAndUpdate({ _id: id }, { userType, adminApproved: true }); - - return true; -}; diff --git a/lib/resolvers/user_query/myLanguage.js b/lib/resolvers/user_query/myLanguage.js deleted file mode 100644 index 2225aa1fdc..0000000000 --- a/lib/resolvers/user_query/myLanguage.js +++ /dev/null @@ -1,28 +0,0 @@ -const User = require('../../models/User'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, -} = require('../../../constants'); - -module.exports = async (parent, args, context) => { - const user = await User.findOne({ - _id: context.userId, - }); - - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - return user.appLanguageCode; -}; diff --git a/lib/resolvers/user_query/tasksByUser.js b/lib/resolvers/user_query/tasksByUser.js deleted file mode 100644 index 93dccddb12..0000000000 --- a/lib/resolvers/user_query/tasksByUser.js +++ /dev/null @@ -1,36 +0,0 @@ -const Task = require('../../models/Task'); - -module.exports = async (parent, args) => { - var sort = {}; - var isSortingExecuted = args.orderBy !== null; - - //Sorting List - if (isSortingExecuted) { - if (args.orderBy === 'id_ASC') { - sort = { _id: 1 }; - } else if (args.orderBy === 'id_DESC') { - sort = { _id: -1 }; - } else if (args.orderBy === 'title_ASC') { - sort = { title: 1 }; - } else if (args.orderBy === 'title_DESC') { - sort = { title: -1 }; - } else if (args.orderBy === 'description_ASC') { - sort = { description: 1 }; - } else if (args.orderBy === 'description_DESC') { - sort = { description: -1 }; - } else if (args.orderBy === 'createdAt_ASC') { - sort = { createdAt: 1 }; - } else if (args.orderBy === 'createdAt_DESC') { - sort = { createdAt: -1 }; - } else if (args.orderBy === 'deadline_ASC') { - sort = { deadline: 1 }; - } else { - sort = { deadline: -1 }; - } - } - - return await Task.find({ creator: args.id }) - .sort(sort) - .populate('event') - .populate('creator', '-password'); -}; diff --git a/lib/resolvers/user_query/userLanguage.js b/lib/resolvers/user_query/userLanguage.js deleted file mode 100644 index 6f31ec1cc9..0000000000 --- a/lib/resolvers/user_query/userLanguage.js +++ /dev/null @@ -1,28 +0,0 @@ -const User = require('../../models/User'); -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const { - IN_PRODUCTION, - USER_NOT_FOUND, - USER_NOT_FOUND_MESSAGE, - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM, -} = require('../../../constants'); - -module.exports = async (parent, args) => { - const user = await User.findOne({ - _id: args.userId, - }); - - if (!user) { - throw new NotFoundError( - !IN_PRODUCTION - ? USER_NOT_FOUND - : requestContext.translate(USER_NOT_FOUND_MESSAGE), - USER_NOT_FOUND_CODE, - USER_NOT_FOUND_PARAM - ); - } - - return user.appLanguageCode; -}; diff --git a/lib/resolvers/user_query/user_filter.js b/lib/resolvers/user_query/user_filter.js deleted file mode 100644 index 513e47af3d..0000000000 --- a/lib/resolvers/user_query/user_filter.js +++ /dev/null @@ -1,276 +0,0 @@ -// The function helps in getting the requested in desired order -const filterParamUtil = (filterParam) => { - var inputArg = {}; - if (filterParam.id) { - inputArg = { - ...inputArg, - _id: filterParam.id, - }; - } - - //Returns all user other than provided id - if (filterParam.id_not) { - inputArg = { - ...inputArg, - _id: { - $ne: filterParam.id_not, - }, - }; - } - - //Return users with id in the provided list - if (filterParam.id_in) { - inputArg = { - ...inputArg, - _id: { - $in: filterParam.id_in, - }, - }; - } - - //Returns user not included in provided id list - if (filterParam.id_not_in) { - inputArg = { - ...inputArg, - _id: { - $nin: filterParam.id_not_in, - }, - }; - } - - //Returns provided firstName user - if (filterParam.firstName) { - inputArg = { - ...inputArg, - firstName: filterParam.firstName, - }; - } - - //Returns user with not that firstName - if (filterParam.firstName_not) { - inputArg = { - ...inputArg, - firstName: { - $ne: filterParam.firstName_not, - }, - }; - } - - //Return users with the given list firstName - if (filterParam.firstName_in) { - inputArg = { - ...inputArg, - firstName: { - $in: filterParam.firstName_in, - }, - }; - } - - //Returns users with firstName not in the provided list - if (filterParam.firstName_not_in) { - inputArg = { - ...inputArg, - firstName: { - $nin: filterParam.firstName_not_in, - }, - }; - } - - //Returns users with first name containing provided string - if (filterParam.firstName_contains) { - inputArg = { - ...inputArg, - firstName: { - $regex: filterParam.firstName_contains, - $options: 'i', - }, - }; - } - - //Returns users with firstName starts with that provided string - if (filterParam.firstName_starts_with) { - const regexp = new RegExp('^' + filterParam.firstName_starts_with); - inputArg = { - ...inputArg, - firstName: regexp, - }; - } - - //Returns lastName user - if (filterParam.lastName) { - inputArg = { - ...inputArg, - lastName: filterParam.lastName, - }; - } - - //Returns user with not that lastName - if (filterParam.lastName_not) { - inputArg = { - ...inputArg, - lastName: { - $ne: filterParam.lastName_not, - }, - }; - } - - //Return users with lastName in provided list - if (filterParam.lastName_in) { - inputArg = { - ...inputArg, - lastName: { - $in: filterParam.lastName_in, - }, - }; - } - - //Return users with lastName not in provided list - if (filterParam.lastName_not_in) { - inputArg = { - ...inputArg, - lastName: { - $nin: filterParam.lastName_not_in, - }, - }; - } - - //Return users with lastName should containing provided string - if (filterParam.lastName_contains) { - inputArg = { - ...inputArg, - lastName: { - $regex: filterParam.lastName_contains, - $options: 'i', - }, - }; - } - - //Returns users with LastName starting with provided string - if (filterParam.lastName_starts_with) { - const regexp = new RegExp('^' + filterParam.lastName_starts_with); - inputArg = { - ...inputArg, - lastName: regexp, - }; - } - - //Returns provided email user - if (filterParam.email) { - inputArg = { - ...inputArg, - email: filterParam.email, - }; - } - - //Returns user with not that provided email - if (filterParam.email_not) { - inputArg = { - ...inputArg, - email: { - $ne: filterParam.email_not, - }, - }; - } - - //User email falls in provided list - if (filterParam.email_in) { - inputArg = { - ...inputArg, - email: { - $in: filterParam.email_in, - }, - }; - } - - //Return User email not falls in the list - if (filterParam.email_not_in) { - inputArg = { - ...inputArg, - email: { - $nin: filterParam.email_not_in, - }, - }; - } - - //Return users with email containing provided string - if (filterParam.email_contains) { - inputArg = { - ...inputArg, - email: { - $regex: filterParam.email_contains, - $options: 'i', - }, - }; - } - - //Returns user with email starts with provided string - if (filterParam.email_starts_with) { - const regexp = new RegExp('^' + filterParam.email_starts_with); - inputArg = { - ...inputArg, - email: regexp, - }; - } - - //Returns provided appLanguageCode user - if (filterParam.appLanguageCode) { - inputArg = { - ...inputArg, - appLanguageCode: filterParam.appLanguageCode, - }; - } - - //Returns user with not that provided appLanguageCode - if (filterParam.appLanguageCode_not) { - inputArg = { - ...inputArg, - appLanguageCode: { - $ne: filterParam.appLanguageCode_not, - }, - }; - } - - //User appLanguageCode falls in provided list - if (filterParam.appLanguageCode_in) { - inputArg = { - ...inputArg, - appLanguageCode: { - $in: filterParam.appLanguageCode_in, - }, - }; - } - - //Return User appLanguageCode not falls in the list - if (filterParam.appLanguageCode_not_in) { - inputArg = { - ...inputArg, - appLanguageCode: { - $nin: filterParam.appLanguageCode_not_in, - }, - }; - } - - //Return users with appLanguageCode containing provided string - if (filterParam.appLanguageCode_contains) { - inputArg = { - ...inputArg, - appLanguageCode: { - $regex: filterParam.appLanguageCode_contains, - $options: 'i', - }, - }; - } - - //Returns user with appLanguageCode starts with provided string - if (filterParam.appLanguageCode_starts_with) { - const regexp = new RegExp('^' + filterParam.email_starts_with); - inputArg = { - ...inputArg, - appLanguageCode: regexp, - }; - } - - return inputArg; -}; - -module.exports = filterParamUtil; diff --git a/lib/resolvers/user_query/user_orderBy.js b/lib/resolvers/user_query/user_orderBy.js deleted file mode 100644 index 9134640f16..0000000000 --- a/lib/resolvers/user_query/user_orderBy.js +++ /dev/null @@ -1,48 +0,0 @@ -const orderByFilter = (orderBy) => { - var sort = {}; - if (orderBy === 'id_ASC') { - sort = { - _id: 1, - }; - } else if (orderBy === 'id_DESC') { - sort = { - _id: -1, - }; - } else if (orderBy === 'firstName_ASC') { - sort = { - firstName: 1, - }; - } else if (orderBy === 'firstName_DESC') { - sort = { - firstName: -1, - }; - } else if (orderBy === 'lastName_ASC') { - sort = { - lastName: 1, - }; - } else if (orderBy === 'lastName_DESC') { - sort = { - lastName: -1, - }; - } else if (orderBy === 'appLanguageCode_ASC') { - sort = { - appLanguageCode: 1, - }; - } else if (orderBy === 'appLanguageCode_DESC') { - sort = { - appLanguageCode: -1, - }; - } else if (orderBy === 'email_ASC') { - sort = { - email: 1, - }; - } else { - sort = { - email: -1, - }; - } - - return sort; -}; - -module.exports = orderByFilter; diff --git a/lib/resolvers/user_query/users.js b/lib/resolvers/user_query/users.js deleted file mode 100644 index d803c26539..0000000000 --- a/lib/resolvers/user_query/users.js +++ /dev/null @@ -1,206 +0,0 @@ -const { NotFoundError } = require('errors'); -const requestContext = require('talawa-request-context'); -const filterParamUtil = require('./user_filter'); -const orderByFilter = require('./user_orderBy'); -const User = require('../../models/User'); -const userExists = require('../../helper_functions/userExists'); - -// Query to provide logged user information -const me = async (parent, args, context) => { - const user = await User.findOne({ - _id: context.userId, - }) - .populate('createdOrganizations') - .populate('createdEvents') - .populate('joinedOrganizations') - .populate('registeredEvents') - .populate('eventAdmin') - .populate('adminFor'); - if (!user) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } - - return { - ...user._doc, - password: null, - }; -}; - -// Display the basic info of any user -// Query doesn't allow to see the blocked by organization -const user = async (parent, args, context) => { - let userFound = await userExists(context.userId); - if (!userFound) throw new Error('User not found'); - - const user = await User.findOne({ _id: args.id }).populate('adminFor'); - - return { - ...user?._doc, - organizationsBlockedBy: [], - }; -}; - -// The query displays the list of users -// Query doesn't allow to see the blocked by organization -const users = async (parent, args) => { - let sort = {}; - let inputArg = {}; - let isSortingExecuted = args.orderBy !== null; - const filterParam = args.where; - - if (filterParam) { - inputArg = filterParamUtil(filterParam); - } - - if (isSortingExecuted) { - sort = orderByFilter(args.orderBy); - } - - const users = await User.find(inputArg) - .sort(sort) - .populate('createdOrganizations') - .populate('createdEvents') - .populate('joinedOrganizations') - .populate('registeredEvents') - .populate('eventAdmin') - .populate('adminFor'); - if (!users[0]) { - throw new NotFoundError( - requestContext.translate('user.notFound'), - 'user.notFound', - 'user' - ); - } else - return users.map((user) => { - return { - ...user._doc, - password: null, - organizationsBlockedBy: [], - }; - }); -}; - -const usersConnection = async (parent, args) => { - var inputArg = {}; - var isSortingExecuted = args.orderBy !== null; - const filterParam = args.where; - - if (filterParam) { - inputArg = filterParamUtil(filterParam); - } - - var sort = {}; - if (isSortingExecuted) { - sort = orderByFilter(args.orderBy); - } - - const users = await User.find(inputArg) - .sort(sort) - .limit(args.first) - .skip(args.skip) - .populate('createdOrganizations') - .populate('createdEvents') - .populate('joinedOrganizations') - .populate('registeredEvents') - .populate('eventAdmin') - .populate('adminFor'); - - return users.map((user) => { - return { - ...user._doc, - password: null, - }; - }); -}; - -const organizationsMemberConnection = async (parent, args) => { - var inputArg = {}; - var sort = {}; - - if (args.where) { - inputArg = filterParamUtil(args.where); - } - - if (args.orderBy) { - sort = orderByFilter(args.orderBy); - } - - // Pagination based Options - var options = {}; - if (args.first) { - if (args.skip === null) { - throw 'Missing Skip parameter. Set it to either 0 or some other value'; - } - - options = { - lean: true, - sort: sort, - pagination: true, - page: args.skip, - limit: args.first, - }; - } else { - options = { - sort: sort, - pagination: false, - }; - } - - const usersModel = await User.paginate( - { - joinedOrganizations: { - _id: args.orgId, - }, - ...inputArg, - }, - options - ); - - var users = {}; - if (options.pagination) { - if (args.skip === undefined) { - throw new Error('Skip parameter is missing'); - } - - users = usersModel.docs.map((user) => { - return { - ...user, - password: null, - }; - }); - } else { - users = usersModel.docs.map((user) => { - return { - ...user._doc, - password: null, - }; - }); - } - - return { - pageInfo: { - hasNextPage: usersModel.hasNextPage, - hasPreviousPage: usersModel.hasPrevPage, - totalPages: usersModel.totalPages, - nextPageNo: usersModel.nextPage, - prevPageNo: usersModel.prevPage, - currPageNo: usersModel.page, - }, - edges: users, - aggregate: { - count: usersModel.totalDocs, - }, - }; -}; - -module.exports = { - me: me, - user: user, - users: users, - usersConnection: usersConnection, - organizationsMemberConnection: organizationsMemberConnection, -}; diff --git a/lib/schema/Language/lang.graphql b/lib/schema/Language/lang.graphql deleted file mode 100644 index bd791acfd6..0000000000 --- a/lib/schema/Language/lang.graphql +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = ` - - type Language { - _id: ID! - en: String! - translation: [LanguageModel] - createdAt: String! - } - - type LanguageModel { - _id: ID! - lang_code: String! - value: String! - verified: Boolean! - createdAt: String! - } - - input LanguageInput{ - en_value: String! - translation_lang_code: String! - translation_value: String! - } - - type Translation{ - lang_code: String - en_value: String - translation: String - verified: Boolean - } - -` \ No newline at end of file diff --git a/lib/schema/chats/chat.graphql b/lib/schema/chats/chat.graphql deleted file mode 100644 index 8cdb3e5499..0000000000 --- a/lib/schema/chats/chat.graphql +++ /dev/null @@ -1,48 +0,0 @@ -module.exports = ` - - type DirectChat { - _id: ID! - users: [User!]! - messages: [DirectChatMessage] - creator: User! - organization: Organization! - } - - type GroupChat { - _id: ID! - users: [User!]! - messages: [GroupChatMessage] - creator: User! - organization: Organization! - } - - type GroupChatMessage { - _id: ID! - groupChatMessageBelongsTo: GroupChat! - sender: User! - createdAt: String! - messageContent: String! - } - - type DirectChatMessage { - _id: ID! - directChatMessageBelongsTo: DirectChat! - sender: User! - receiver: User! - createdAt: String! - messageContent: String! - } - - input createChatInput { - userIds: [ID!]! - organizationId: ID! - } - - input createGroupChatInput { - userIds: [ID!]! - organizationId: ID! - title: String! - } - - -` \ No newline at end of file diff --git a/lib/schema/chats/message.graphql b/lib/schema/chats/message.graphql deleted file mode 100644 index 1ba0c2dfb2..0000000000 --- a/lib/schema/chats/message.graphql +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = ` - type MessageChat { - _id: ID! - sender: User! - receiver: User! - message: String! - languageBarrier: Boolean - createdAt: String! - } - - input MessageChatInput { - message: String! - receiver: ID! - } -` \ No newline at end of file diff --git a/lib/schema/event/event.graphql b/lib/schema/event/event.graphql deleted file mode 100644 index 625e5852c6..0000000000 --- a/lib/schema/event/event.graphql +++ /dev/null @@ -1,150 +0,0 @@ -module.exports = ` - type Event { - _id: ID! - title:String! - description: String! - startDate: String! - endDate: String! - startTime: String - endTime: String - allDay: Boolean! - recurring: Boolean! - recurrance: Recurrance - isPublic: Boolean! - isRegisterable: Boolean! - location: String - latitude: Float - longitude: Float - organization: Organization - creator: User! - registrants: [UserAttende] - admins(adminId: ID): [User] - tasks: [Task] - status: Status! - } - - type EventRegistrants{ - event: Event! - isRegistered: Boolean! - } - - type UserAttende{ - _id: ID! - userId: String! - user: User! - status: Status! - createdAt: String - } - - input EventInput { - title:String! - description: String! - startDate: String! - endDate: String - startTime: String - endTime: String - allDay: Boolean! - recurring: Boolean! - recurrance: Recurrance - isPublic: Boolean! - isRegisterable: Boolean! - location: String - latitude: Float - longitude: Float - organizationId: ID! - } - - # type EventProject { - # _id: ID! - # title:String! - # description: String! - # event: Event! - # tasks: [Task] - # } - - type Task { - _id: ID! - title: String! - description: String - event: Event! - creator: User! - createdAt: String! - deadline: String - } - - input UpdateEventInput { - title:String - description: String - recurring: Boolean - recurrance: Recurrance - isPublic: Boolean - isRegisterable: Boolean - startDate: String - endDate: String - location: String - latitude: Float - longitude: Float - allDay: Boolean - startTime: String - endTime: String - } - - input TaskInput { - title: String! - description: String - deadline: String - } - - input UpdateTaskInput { - title: String - description: String - deadline: String - } - - enum EventOrderByInput { - id_ASC - id_DESC - title_ASC - title_DESC - description_ASC - description_DESC - startDate_ASC - startDate_DESC - endDate_ASC - endDate_DESC - allDay_ASC - allDay_DESC - startTime_ASC - startTime_DESC - endTime_ASC - endTime_DESC - recurrance_ASC - recurrance_DESC - location_ASC - location_DESC - } - - enum TaskOrderByInput { - id_ASC - id_DESC - title_ASC - title_DESC - description_ASC - description_DESC - createdAt_ASC - createdAt_DESC - deadline_ASC - deadline_DESC - } - -# input EventProjectInput { -# title:String! -# description: String! -# eventId: String -# } - -# input UpdateEventProjectInput { -# title:String -# description: String -# } -# ` \ No newline at end of file diff --git a/lib/schema/mutation.graphql b/lib/schema/mutation.graphql deleted file mode 100644 index b1e619861d..0000000000 --- a/lib/schema/mutation.graphql +++ /dev/null @@ -1,88 +0,0 @@ -module.exports = ` - - type Mutation { - signUp(data: UserInput!, file:Upload): AuthData! - login(data: LoginInput!): AuthData! - otp(data: OTPInput!): OtpData! - recaptcha(data: RecaptchaVerification!): Boolean! - forgotPassword(data: ForgotPasswordData!): Boolean! - saveFcmToken(token: String) : Boolean! @auth - refreshToken(refreshToken: String!) : ExtendSession! - revokeRefreshTokenForUser(userId: String!) : Boolean! - updateLanguage(languageCode: String!) : User! @auth - logout: Boolean! @auth - - updateUserProfile(data: UpdateUserInput, file:Upload): User! @auth - updateUserType(data: UpdateUserTypeInput!): Boolean! @auth - createEvent(data: EventInput): Event! @auth - removeEvent(id: ID!): Event! @auth - registerForEvent(id: ID!): Event! @auth - unregisterForEventByUser(id: ID!): Event! @auth - updateEvent(id:ID!, data: UpdateEventInput) : Event! @auth - - createOrganization(data: OrganizationInput, file:Upload): Organization! @auth - updateOrganization(id:ID!, data: UpdateOrganizationInput) : Organization! @auth - removeOrganization(id: ID!) : User! @auth - - acceptAdmin(id: ID!): Boolean! @auth - rejectAdmin(id: ID!): Boolean! @auth - - createAdmin (data: UserAndOrganizationInput!) : User! @auth - removeAdmin (data: UserAndOrganizationInput!) : User! @auth - joinPublicOrganization (organizationId: ID!) : User! @auth - leaveOrganization (organizationId: ID!) : User! @auth - removeMember (data: MultipleUsersAndOrganizationInput!) : Organization! @auth - - adminRemovePost(organizationId: ID!, postId:ID!):Post! @auth - adminRemoveEvent(eventId: ID!): Event! @auth - adminRemoveGroup(groupId:ID!):Message! @auth - - createPost(data: PostInput!, file: Upload): Post @auth - removePost(id:ID!): Post @auth - likePost(id:ID!): Post @auth - unlikePost(id:ID!): Post @auth - - createComment(postId:ID!, data: CommentInput!): Comment @auth - removeComment(id:ID!): Comment @auth - likeComment(id:ID!): Comment @auth - unlikeComment(id:ID!): Comment @auth - - createTask(data: TaskInput, eventId: ID!): Task! @auth - updateTask(id:ID!, data: UpdateTaskInput) : Task @auth - removeTask(id: ID!) : Task @auth - - createGroup(data: GroupInput!): Group! @auth - - sendMembershipRequest(organizationId: ID!) : MembershipRequest! @auth - acceptMembershipRequest(membershipRequestId: ID!): MembershipRequest! @auth - rejectMembershipRequest(membershipRequestId: ID!): MembershipRequest! @auth - cancelMembershipRequest(membershipRequestId: ID!) : MembershipRequest! @auth - - blockUser(organizationId: ID!, userId: ID!) : User! @auth - unblockUser(organizationId: ID!, userId:ID!) : User! @auth - - addUserImage(file: Upload!): User! @auth - removeUserImage: User! @auth - addOrganizationImage(file: Upload!, organizationId: String!): Organization! @auth - removeOrganizationImage(organizationId: String!): Organization! @auth - - createDirectChat(data: createChatInput): DirectChat! @auth - removeDirectChat(chatId: ID!, organizationId: ID!) : DirectChat! @auth - sendMessageToDirectChat(chatId: ID!, messageContent: String!): DirectChatMessage! @auth - - createGroupChat(data: createGroupChatInput): GroupChat! @auth - removeGroupChat(chatId: ID!): GroupChat! @auth - sendMessageToGroupChat(chatId: ID!, messageContent: String!): GroupChatMessage! @auth - addUserToGroupChat(userId: ID!, chatId: ID!): GroupChat! @auth - removeUserFromGroupChat(userId: ID!, chatId: ID!): GroupChat! @auth - blockPluginCreationBySuperadmin(userId: ID!, blockUser: Boolean!): User! @auth - - createMessageChat(data:MessageChatInput!): MessageChat! @auth - addLanguageTranslation(data: LanguageInput!): Language! @auth - - createPlugin(pluginName: String! , pluginCreatedBy: String! ,pluginDesc: String! ,pluginInstallStatus: Boolean!, installedOrgs:[ID!] ):Plugin! - updatePluginStatus(id: ID!, status: Boolean!) : Plugin! - updatePluginInstalledOrgs(id: ID! ,orgId: ID!) :Plugin! - } - -` diff --git a/lib/schema/plugin/plugin.graphql b/lib/schema/plugin/plugin.graphql deleted file mode 100644 index c64d18475c..0000000000 --- a/lib/schema/plugin/plugin.graphql +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = ` - # type Plugin { - # orgId: Organization! - # pluginName: String! - # pluginKey: String - # pluginStatus: Status! - # pluginType: Type! - # additionalInfo: [PluginField!] - # createdAt: String - # } - - input PluginInput{ - orgId: ID! - pluginName: String! - pluginKey: String - pluginType: Type - fields: [PluginFieldInput] - } - - input PluginFieldInput{ - key: String! - value: String! - } - - # For Plugins - type Plugin { - _id: ID! - pluginName: String! - pluginCreatedBy: String! - pluginDesc: String! - pluginInstallStatus: Boolean! - installedOrgs : [ID!]! - } - -` \ No newline at end of file diff --git a/lib/schema/plugin/pluginField.graphql b/lib/schema/plugin/pluginField.graphql deleted file mode 100644 index 4c351cd520..0000000000 --- a/lib/schema/plugin/pluginField.graphql +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = ` - type PluginField { - key: String! - value: String! - status: Status! - createdAt: String - } -` \ No newline at end of file diff --git a/lib/schema/schema.graphql b/lib/schema/schema.graphql deleted file mode 100644 index 8e9d8cdd5b..0000000000 --- a/lib/schema/schema.graphql +++ /dev/null @@ -1,66 +0,0 @@ -const { gql } = require("apollo-server-express"); -const mutation = require("./mutation.graphql"); -const query = require("./query.graphql"); -const utils = require("./utils.graphql"); -const user = require("./user/user.graphql"); -const auth = require("./user/auth.graphql"); -const organization = require("./organization/organization.graphql"); -const event = require("./event/event.graphql"); -const newsfeed = require("./newsfeed/newsfeed.graphql"); -const chats = require("./chats/chat.graphql"); -const plugins = require("./plugin/plugin.graphql"); -const pluginfields = require("./plugin/pluginField.graphql"); -const message = require("./chats/message.graphql"); -const language = require("./Language/lang.graphql"); - -const typeDefs = gql` - directive @auth on FIELD_DEFINITION - directive @role(requires: UserType) on FIELD_DEFINITION - - type Message { - _id: ID! - text: String - createdAt: String - imageUrl: String - videoUrl:String - creator: User - } - - input GroupInput { - title: String - description:String - organizationId: ID! - } - - type Group { - _id: ID - title: String - description:String - createdAt:String - organization: Organization! - admins: [User] - } - - ${mutation} - ${query} - ${user} - ${auth} - ${organization} - ${event} - ${newsfeed} - ${chats} - ${utils} - ${plugins} - ${pluginfields} - ${message} - ${language} - - type Subscription { - messageSentToDirectChat: DirectChatMessage - messageSentToGroupChat: GroupChatMessage - directMessageChat: MessageChat - } -` - - -module.exports = typeDefs \ No newline at end of file diff --git a/lib/schema/utils.graphql b/lib/schema/utils.graphql deleted file mode 100644 index 9c563e988f..0000000000 --- a/lib/schema/utils.graphql +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = ` - - """Information about pagination in a connection.""" - type PageInfo { - """When paginating forwards, are there more items?""" - hasNextPage: Boolean! - - """When paginating backwards, are there more items?""" - hasPreviousPage: Boolean! - totalPages: Int - nextPageNo: Int - prevPageNo: Int - currPageNo: Int - } - - enum Status{ - ACTIVE - BLOCKED - DELETED - } - - enum UserType{ - USER - ADMIN - SUPERADMIN - } - - enum Recurrance{ - DAILY - WEEKLY - MONTHLY - YEARLY - ONCE - } - enum Type{ - UNIVERSAL - PRIVATE - } - -` \ No newline at end of file diff --git a/locales/README.md b/locales/README.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/package-lock.json b/package-lock.json index 8dad0d2e6a..c640c700d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,116 +9,114 @@ "version": "1.0.0", "license": "GNU General Public License v3.0", "dependencies": { - "@graphql-tools/schema": "^8.3.5", - "apollo-server-core": "^3.10.1", - "apollo-server-express": "^2.25.2", - "axios": "^0.21.2", + "@graphql-tools/schema": "^8.4.0", + "apollo-server-core": "^3.11.1", + "apollo-server-express": "^2.25.4", + "axios": "^0.21.4", "bcryptjs": "^2.4.3", - "boxen": "^4.2.0", - "chalk": "^4.1.0", "cls-bluebird": "^2.1.0", "cls-hooked": "^4.2.2", "copy-paste": "^1.3.0", "cors": "^2.8.5", "cross-env": "^7.0.3", "dotenv": "^8.6.0", - "errors": "file:lib/helper_lib/errors", - "express": "^4.17.1", - "express-mongo-sanitize": "^2.0.2", - "express-rate-limit": "^5.2.6", + "express": "^4.18.1", + "express-mongo-sanitize": "^2.2.0", + "express-rate-limit": "^5.5.1", "firebase-admin": "^10.3.0", - "glob-parent": "^5.1.2", - "graphql": "^15.5.0", + "graphql": "^15.8.0", "graphql-depth-limit": "^1.1.0", "graphql-upload": "^12.0.0", - "graphql-ws": "^5.6.4", "helmet": "^4.6.0", - "i18n": "^0.13.3", + "i18n": "^0.13.4", "image-hash": "^4.0.1", - "inquirer": "^8.2.4", "jsonwebtoken": "^8.5.1", "jwt-decode": "^3.1.2", - "logger": "file:lib/helper_lib/logger", - "markdown-js": "^0.0.4", - "marked": "^2.0.1", - "marked-terminal": "^5.1.1", - "moment": "^2.29.4", - "mongoose": "^5.13.0", - "mongoose-paginate-v2": "^1.3.18", + "lodash": "^4.17.21", + "mongoose": "^5.13.14", + "mongoose-paginate-v2": "^1.7.0", "morgan": "^1.10.0", - "netmask": ">=2.0.1", - "node-cmd": "^5.0.0", - "nodemailer": "^6.7.5", - "pm2": "^5.1.2", - "request-tracing": "file:lib/helper_lib/request-tracing", + "nanoid": "^3.3.4", + "nodemailer": "^6.7.8", + "pm2": "^5.2.0", "shortid": "^2.2.16", - "talawa-request-context": "file:lib/helper_lib/talawa-request-context", "uuid": "^3.4.0", "validator": "^13.7.0", - "winston": "^3.3.3", - "ws": "^7.5.7", - "xss-clean": "^0.1.1", - "yarn": "^1.22.10" + "winston": "^3.8.0", + "xss-clean": "^0.1.1" }, "devDependencies": { - "easygraphql-tester": "^5.1.6", - "eslint": "^7.29.0", - "eslint-config-airbnb-base": "^14.2.1", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.23.4", - "eslint-plugin-jest": "^24.3.6", - "eslint-plugin-prettier": "^3.4.0", - "jest": "^27.4.7", - "netmask": ">=2.0.1", - "nodemon": "^2.0.15", - "prettier": "^2.3.2" - } - }, - "lib/helper_lib/errors": { - "version": "1.0.0", - "license": "GNU General Public License v3.0" - }, - "lib/helper_lib/logger": { - "version": "1.0.0", - "license": "GNU General Public License v3.0", - "dependencies": { - "lodash": "^4.17.21", - "winston": "^3.3.3" + "@graphql-codegen/cli": "^2.6.2", + "@graphql-codegen/typescript": "^2.5.1", + "@graphql-codegen/typescript-resolvers": "^2.6.6", + "@graphql-eslint/eslint-plugin": "^3.12.0", + "@types/bcryptjs": "^2.4.2", + "@types/cls-hooked": "^4.3.3", + "@types/copy-paste": "^1.1.30", + "@types/express": "^4.17.13", + "@types/express-rate-limit": "^5.1.3", + "@types/graphql-depth-limit": "^1.1.3", + "@types/i18n": "^0.13.3", + "@types/jsonwebtoken": "^8.5.8", + "@types/lodash": "^4.14.182", + "@types/mongoose-paginate-v2": "^1.6.5", + "@types/morgan": "^1.9.3", + "@types/node": "^18.11.9", + "@types/nodemailer": "^6.4.5", + "@types/shortid": "^0.0.29", + "@types/uuid": "^3.4.10", + "@types/validator": "^13.7.3", + "@typescript-eslint/eslint-plugin": "^5.42.0", + "@typescript-eslint/parser": "^5.42.0", + "@vitest/coverage-c8": "^0.24.3", + "boxen": "^4.2.0", + "chalk": "^4.1.2", + "concurrently": "^7.5.0", + "copyfiles": "^2.4.1", + "eslint": "^8.26.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-prettier": "^4.2.1", + "inquirer": "^8.2.4", + "marked": "^2.1.3", + "marked-terminal": "^4.2.0", + "node-cmd": "^5.0.0", + "prettier": "^2.7.1", + "rimraf": "^3.0.2", + "tsx": "^3.11.0", + "typescript": "^4.8.4", + "vitest": "^0.24.3" } }, - "lib/helper_lib/request-tracing": { - "version": "1.0.0", - "license": "GNU General Public License v3.0", + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, "dependencies": { - "cls-bluebird": "^2.1.0", - "cls-hooked": "^4.2.2", - "nanoid": "^3.1.31" - } - }, - "lib/helper_lib/request-tracing/node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "bin": { - "nanoid": "bin/nanoid.cjs" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=6.0.0" } }, - "lib/helper_lib/talawa-request-context": { - "version": "1.0.0", - "license": "GNU General Public License v3.0", + "node_modules/@ampproject/remapping/node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, "dependencies": { - "cls-bluebird": "^2.1.0", - "cls-hooked": "^4.2.2", - "i18n": "^0.13.3" + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/@apollo/protobufjs": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", - "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.6.tgz", + "integrity": "sha512-Wqo1oSHNUj/jxmsVp4iR3I480p6qdqHikn38lKrFhfzcDJ7lwd7Ck7cHRl4JE81tWNArl77xhnG/OkZhxKBYOw==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -166,17 +164,17 @@ } }, "node_modules/@apollo/utils.keyvaluecache/node_modules/lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", "engines": { "node": ">=12" } }, "node_modules/@apollo/utils.logger": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.0.tgz", - "integrity": "sha512-dx9XrjyisD2pOa+KsB5RcDbWIAdgC91gJfeyLCgy0ctJMjQe7yZK5kdWaWlaOoCeX0z6YI9iYlg7vMPyMpQF3Q==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.1.tgz", + "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==" }, "node_modules/@apollo/utils.printwithreducedwhitespace": { "version": "1.1.0", @@ -244,44 +242,6 @@ "graphql": "14.x || 15.x || 16.x" } }, - "node_modules/@apollo/utils.usagereporting/node_modules/@apollo/protobufjs": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.4.tgz", - "integrity": "sha512-npVJ9NVU/pynj+SCU+fambvTneJDyCnif738DnZ7pCxdDtzeEz7WkpSIq5wNUmWm5Td55N+S2xfqZ+WP4hDLng==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - }, - "bin": { - "apollo-pbjs": "bin/pbjs", - "apollo-pbts": "bin/pbts" - } - }, - "node_modules/@apollo/utils.usagereporting/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" - }, - "node_modules/@apollo/utils.usagereporting/node_modules/apollo-reporting-protobuf": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.2.tgz", - "integrity": "sha512-j1tx9tmkVdsLt1UPzBrvz90PdjAeKW157WxGn+aXlnnGfVjZLIRXX3x5t1NWtXvB7rVaAsLLILLtDHW382TSoQ==", - "dependencies": { - "@apollo/protobufjs": "1.2.4" - } - }, "node_modules/@apollographql/apollo-tools": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.4.tgz", @@ -295,20 +255,20 @@ } }, "node_modules/@apollographql/graphql-playground-html": { - "version": "1.6.27", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.27.tgz", - "integrity": "sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw==", + "version": "1.6.29", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz", + "integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==", "dependencies": { "xss": "^1.0.8" } }, "node_modules/@apollographql/graphql-upload-8-fork": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz", - "integrity": "sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g==", + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.4.tgz", + "integrity": "sha512-lHAj/PUegYu02zza9Pg0bQQYH5I0ah1nyIzu2YIqOv41P0vu3GCBISAmQCfFHThK7N3dy7dLFPhoKcXlXRLPoQ==", "dependencies": { "@types/express": "*", - "@types/fs-capacitor": "*", + "@types/fs-capacitor": "^2.0.0", "@types/koa": "*", "busboy": "^0.3.1", "fs-capacitor": "^2.0.4", @@ -322,325 +282,531 @@ "graphql": "0.13.1 - 15" } }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, + "node_modules/@apollographql/graphql-upload-8-fork/node_modules/busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", "dependencies": { - "@babel/highlight": "^7.10.4" + "dicer": "0.3.0" + }, + "engines": { + "node": ">=4.5.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", - "dev": true, + "node_modules/@apollographql/graphql-upload-8-fork/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "engines": { - "node": ">=6.9.0" + "node": ">= 0.6" } }, - "node_modules/@babel/core": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", - "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.16.7", - "@babel/parser": "^7.16.12", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.10", - "@babel/types": "^7.16.8", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, + "node_modules/@apollographql/graphql-upload-8-fork/node_modules/fs-capacitor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", + "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==", "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "node": ">=8.5" } }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, + "node_modules/@apollographql/graphql-upload-8-fork/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dependencies": { - "@babel/highlight": "^7.16.7" + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.6" } }, - "node_modules/@babel/core/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, + "node_modules/@apollographql/graphql-upload-8-fork/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 0.6" } }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "node_modules/@ardatan/relay-compiler": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz", + "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==", "dev": true, "dependencies": { - "minimist": "^1.2.5" + "@babel/core": "^7.14.0", + "@babel/generator": "^7.14.0", + "@babel/parser": "^7.14.0", + "@babel/runtime": "^7.0.0", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.0.0", + "babel-preset-fbjs": "^3.4.0", + "chalk": "^4.0.0", + "fb-watchman": "^2.0.0", + "fbjs": "^3.0.0", + "glob": "^7.1.1", + "immutable": "~3.7.6", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "relay-runtime": "12.0.0", + "signedsource": "^1.0.0", + "yargs": "^15.3.1" }, "bin": { - "json5": "lib/cli.js" + "relay-compiler": "bin/relay-compiler" }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/core/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "peerDependencies": { + "graphql": "*" } }, - "node_modules/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "node_modules/@ardatan/relay-compiler/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "node_modules/@babel/generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", - "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", + "node_modules/@ardatan/relay-compiler/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.8", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "node_modules/@ardatan/relay-compiler/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "node_modules/@ardatan/relay-compiler/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=6" }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "node_modules/@ardatan/relay-compiler/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "node_modules/@ardatan/relay-compiler/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "node_modules/@ardatan/relay-compiler/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/@ardatan/relay-compiler/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "node_modules/@ardatan/relay-compiler/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=6" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "node_modules/@ardatan/sync-fetch": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz", + "integrity": "sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "node-fetch": "^2.6.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=14" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/highlight": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "node_modules/@babel/compat-data": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", + "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" + "node_modules/@babel/core": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", + "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.6", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helpers": "^7.19.4", + "@babel/parser": "^7.19.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.6", + "@babel/types": "^7.19.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "node_modules/@babel/generator": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.1.tgz", + "integrity": "sha512-u1dMdBUmA7Z0rBB97xh8pIhviK7oItYOkjbsCxTWMknyvbQRBwX7/gn4JXurRdirWMFh+ZtYARqkA6ydogVZpg==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.20.0", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "dev": true, - "engines": { + "dependencies": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", + "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.19.4", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.6", + "@babel/types": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true, + "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", - "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", + "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -674,10 +840,25 @@ "node": ">=4" } }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -686,7 +867,7 @@ "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -705,9 +886,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", - "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.1.tgz", + "integrity": "sha512-hp0AYxaZJhxULfM1zyp7Wgr+pSUKBcP3M+PHnSzWGdXOzg/kHWIgiUWARvubhUKGOEw3xqY4x+lyZ9ytBVcELw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -716,25 +897,36 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", + "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -752,109 +944,138 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", + "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.0.tgz", + "integrity": "sha512-sXOohbpHZSk7GjxK9b3dKB7CfqUD5DwOH+DggKzOQ7TXYP+RCSbRykfjQmn/zq+rBjycVRtLf9pYhAaEJA786w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/@babel/plugin-transform-classes": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.0.tgz", + "integrity": "sha512-1dIhvZfkDVx/zn2S1aFwlruspTt4189j7fEkH0Y0VyuDM6bQt7bD6kLcz3l4IlLG+e5OReaBz9ROAbttRtUHqA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -863,13 +1084,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", + "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-flow": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -878,199 +1100,430 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", - "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dev": true, "dependencies": { - "regenerator-runtime": "^0.13.4" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", - "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.16.10", - "@babel/types": "^7.16.8", - "debug": "^4.1.0", - "globals": "^11.1.0" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", + "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-simple-access": "^7.19.4" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" }, "engines": { - "node": ">=6.0" + "node": ">=6.9.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.1.tgz", + "integrity": "sha512-nDvKLrAvl+kf6BOy1UJ3MGwzzfTMgppxwiD2Jb4LO3xjYyZq30oQzDNJbCQpMdG9+j2IXHoiMrw5Cm/L6ZoxXQ==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, "engines": { - "node": ">=4" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@babel/types": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", - "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=0.1.90" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", + "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.1", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.1", + "@babel/types": "^7.20.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.0.tgz", + "integrity": "sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, + "node_modules/@esbuild-kit/cjs-loader": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.0.tgz", + "integrity": "sha512-DBBCiHPgL2B/elUpvCDhNHXnlZQ9sfO2uyt1OJyAXKT41beQEFY4OxZ6gwS+ZesRCbZ6JV8M7GEyOPkjv8kdIw==", + "dev": true, + "dependencies": { + "@esbuild-kit/core-utils": "^3.0.0", + "get-tsconfig": "^4.2.0" + } + }, + "node_modules/@esbuild-kit/core-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.0.0.tgz", + "integrity": "sha512-TXmwH9EFS3DC2sI2YJWJBgHGhlteK0Xyu1VabwetMULfm3oYhbrsWV5yaSr2NTWZIgDGVLHbRf0inxbjXqAcmQ==", + "dev": true, + "dependencies": { + "esbuild": "~0.15.10", + "source-map-support": "^0.5.21" + } + }, + "node_modules/@esbuild-kit/esm-loader": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.5.0.tgz", + "integrity": "sha512-ySs0qOsiwj+hsgZM9/MniGdvfa9/WzqfFuIia8/5gSUPeIQIX2/tG91QakxPFOR35VFiwTB7wCiHtiS6dc6SkA==", + "dev": true, + "dependencies": { + "@esbuild-kit/core-utils": "^3.0.0", + "get-tsconfig": "^4.2.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz", + "integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz", + "integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dev": true, "dependencies": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "dependencies": { - "ms": "2.1.2" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=6.0" + "node": ">=8" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { - "node": ">= 4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@fastify/busboy": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.1.0.tgz", @@ -1083,75 +1536,75 @@ } }, "node_modules/@firebase/app-types": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", - "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.8.1.tgz", + "integrity": "sha512-p75Ow3QhB82kpMzmOntv866wH9eZ3b4+QbUY+8/DA5Zzdf1c8Nsk8B7kbFpzJt4wwHMdy5LTF5YUnoTc1JiWkw==" }, "node_modules/@firebase/auth-interop-types": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", - "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.7.tgz", + "integrity": "sha512-yA/dTveGGPcc85JP8ZE/KZqfGQyQTBCV10THdI8HTlP1GDvNrhr//J5jAt58MlsCOaO3XmC4DqScPBbtIsR/EA==", "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "node_modules/@firebase/component": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.15.tgz", - "integrity": "sha512-VRnZxmvtJmXupTPg37LxM0zdyMN54EXkmsFD4x5Bm4eZUay9VGnhfiGnE3m9Af/2hnURA2idIBN/23L6982iPQ==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.21.tgz", + "integrity": "sha512-12MMQ/ulfygKpEJpseYMR0HunJdlsLrwx2XcEs40M18jocy2+spyzHHEwegN3x/2/BLFBjR5247Etmz0G97Qpg==", "dependencies": { - "@firebase/util": "1.6.1", + "@firebase/util": "1.7.3", "tslib": "^2.1.0" } }, "node_modules/@firebase/database": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.13.1.tgz", - "integrity": "sha512-k6PeAzf9x9DG3AJtA6SkJsTD1ivOWvrV71VPOYabBch05QDB0HOYs1EauGhzqa6GOcYz+ncb4pNEkgFDvcnEfQ==", - "dependencies": { - "@firebase/auth-interop-types": "0.1.6", - "@firebase/component": "0.5.15", - "@firebase/logger": "0.3.3", - "@firebase/util": "1.6.1", + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.13.10.tgz", + "integrity": "sha512-KRucuzZ7ZHQsRdGEmhxId5jyM2yKsjsQWF9yv0dIhlxYg0D8rCVDZc/waoPKA5oV3/SEIoptF8F7R1Vfe7BCQA==", + "dependencies": { + "@firebase/auth-interop-types": "0.1.7", + "@firebase/component": "0.5.21", + "@firebase/logger": "0.3.4", + "@firebase/util": "1.7.3", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "node_modules/@firebase/database-compat": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.2.1.tgz", - "integrity": "sha512-xpru5ZtO7um2FmfIw4gCAbkWpyOEwxzamU/5phuwze3ZihMdh+UrDrwrhvfqzQ/KIKXsK76Uyx5F3NCAS8+5eg==", - "dependencies": { - "@firebase/component": "0.5.15", - "@firebase/database": "0.13.1", - "@firebase/database-types": "0.9.9", - "@firebase/logger": "0.3.3", - "@firebase/util": "1.6.1", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.2.10.tgz", + "integrity": "sha512-fK+IgUUqVKcWK/gltzDU+B1xauCOfY6vulO8lxoNTkcCGlSxuTtwsdqjGkFmgFRMYjXFWWJ6iFcJ/vXahzwCtA==", + "dependencies": { + "@firebase/component": "0.5.21", + "@firebase/database": "0.13.10", + "@firebase/database-types": "0.9.17", + "@firebase/logger": "0.3.4", + "@firebase/util": "1.7.3", "tslib": "^2.1.0" } }, "node_modules/@firebase/database-types": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.9.tgz", - "integrity": "sha512-Zp86fHzQFZKYVM7yDWVAgVTeOJ39g2wT0ijeiN0jpHAHceeoV013q3jPIIGuooV2HMwWOTIBZGqh+DxrHMFyUw==", + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.17.tgz", + "integrity": "sha512-YQm2tCZyxNtEnlS5qo5gd2PAYgKCy69tUKwioGhApCFThW+mIgZs7IeYeJo2M51i4LCixYUl+CvnOyAnb/c3XA==", "dependencies": { - "@firebase/app-types": "0.7.0", - "@firebase/util": "1.6.1" + "@firebase/app-types": "0.8.1", + "@firebase/util": "1.7.3" } }, "node_modules/@firebase/logger": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.3.tgz", - "integrity": "sha512-POTJl07jOKTOevLXrTvJD/VZ0M6PnJXflbAh5J9VGkmtXPXNG6MdZ9fmRgqYhXKTaDId6AQenQ262uwgpdtO0Q==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.4.tgz", + "integrity": "sha512-hlFglGRgZEwoyClZcGLx/Wd+zoLfGmbDkFx56mQt/jJ0XMbfPqwId1kiPl0zgdWZX+D8iH+gT6GuLPFsJWgiGw==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@firebase/util": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.6.1.tgz", - "integrity": "sha512-+eDE6uG5GgvXYHbAzfP1mpJUX1VDBD+A8CjBeBoNAKAVAApMSDxDODqRcOq7NW7kFJXSUkMzDJWhnUIifX2R8w==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.7.3.tgz", + "integrity": "sha512-wxNqWbqokF551WrJ9BIFouU/V5SL1oYCGx1oudcirdhadnQRFH5v1sjgGL7cUV/UsekSycygphdrF2lxBxOYKg==", "dependencies": { "tslib": "^2.1.0" } @@ -1184,15 +1637,6 @@ "node": ">=10" } }, - "node_modules/@google-cloud/paginator/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@google-cloud/projectify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz", @@ -1245,42 +1689,6 @@ "node": ">=10" } }, - "node_modules/@google-cloud/storage/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@google-cloud/storage/node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@google-cloud/storage/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "optional": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@google-cloud/storage/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -1290,2196 +1698,2435 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/@graphql-toolkit/common": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@graphql-toolkit/common/-/common-0.10.4.tgz", - "integrity": "sha512-HQ3HaxCqX+UE8y/0h7LMDBBGSIKJxY/gaQesaksvE2Y+N4NpSWdiW6HpOcgXfC2HGf9yM0hEdsERzzL8z3mbHQ==", - "deprecated": "GraphQL Toolkit is deprecated and merged into GraphQL Tools, so it will no longer get updates. Use GraphQL Tools instead to stay up-to-date! Check out https://www.graphql-tools.com/docs/migration-from-toolkit for migration and https://the-guild.dev/blog/graphql-tools-v6 for new changes.", + "node_modules/@graphql-codegen/cli": { + "version": "2.13.11", + "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-2.13.11.tgz", + "integrity": "sha512-PJF36a1i6M7Btj1kB4PWWzBUO3u2BJzsd/6KXxRmEugcxrbaCnbTDDktopy0CZYKdqaFbXaowwbRY8Tk8DV99Q==", + "dev": true, + "dependencies": { + "@babel/generator": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/types": "^7.18.13", + "@graphql-codegen/core": "2.6.5", + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-tools/apollo-engine-loader": "^7.3.6", + "@graphql-tools/code-file-loader": "^7.3.1", + "@graphql-tools/git-loader": "^7.2.1", + "@graphql-tools/github-loader": "^7.3.6", + "@graphql-tools/graphql-file-loader": "^7.5.0", + "@graphql-tools/json-file-loader": "^7.4.1", + "@graphql-tools/load": "7.8.0", + "@graphql-tools/prisma-loader": "^7.2.7", + "@graphql-tools/url-loader": "^7.13.2", + "@graphql-tools/utils": "^8.9.0", + "@whatwg-node/fetch": "^0.3.0", + "ansi-escapes": "^4.3.1", + "chalk": "^4.1.0", + "chokidar": "^3.5.2", + "cosmiconfig": "^7.0.0", + "cosmiconfig-typescript-loader": "4.1.1", + "debounce": "^1.2.0", + "detect-indent": "^6.0.0", + "graphql-config": "4.3.6", + "inquirer": "^8.0.0", + "is-glob": "^4.0.1", + "json-to-pretty-yaml": "^1.2.2", + "listr2": "^4.0.5", + "log-symbols": "^4.0.0", + "mkdirp": "^1.0.4", + "shell-quote": "^1.7.3", + "string-env-interpolation": "^1.0.1", + "ts-log": "^2.2.3", + "tslib": "^2.4.0", + "yaml": "^1.10.0", + "yargs": "^17.0.0" + }, + "bin": { + "gql-gen": "cjs/bin.js", + "graphql-code-generator": "cjs/bin.js", + "graphql-codegen": "cjs/bin.js", + "graphql-codegen-esm": "esm/bin.js" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@graphql-codegen/core": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-2.6.5.tgz", + "integrity": "sha512-oSbM8vINFxcV1GUasJTDIemMpEG1t6NkBG8odQCt/3ZExCYmoviHhG9vJB89QqJeU5W06qQB6SJn/dg/gv5Aqg==", "dev": true, "dependencies": { - "aggregate-error": "3.0.1", - "camel-case": "4.1.1", - "graphql-tools": "5.0.0", - "lodash": "4.17.15" + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-tools/schema": "^9.0.0", + "@graphql-tools/utils": "9.0.0", + "tslib": "~2.4.0" }, "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-toolkit/common/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/@graphql-codegen/core/node_modules/@graphql-tools/merge": { + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" }, - "engines": { - "node": ">= 6" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-toolkit/common/node_modules/graphql-tools": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-5.0.0.tgz", - "integrity": "sha512-5zn3vtn//382b7G3Wzz3d5q/sh+f7tVrnxeuhTMTJ7pWJijNqLxH7VEzv8VwXCq19zAzHYEosFHfXiK7qzvk7w==", - "deprecated": "This package has been deprecated and now it only exports makeExecutableSchema.\\nAnd it will no longer receive updates.\\nWe recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc.\\nCheck out https://www.graphql-tools.com to learn what package you should use instead", + "node_modules/@graphql-codegen/core/node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "apollo-link": "^1.2.14", - "apollo-upload-client": "^13.0.0", - "deprecated-decorator": "^0.1.6", - "form-data": "^3.0.0", - "iterall": "^1.3.0", - "node-fetch": "^2.6.0", - "tslib": "^1.11.1", - "uuid": "^7.0.3" + "tslib": "^2.4.0" }, "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-toolkit/common/node_modules/lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "node_modules/@graphql-toolkit/common/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/@graphql-toolkit/common/node_modules/uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "node_modules/@graphql-codegen/core/node_modules/@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "dependencies": { + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-toolkit/file-loading": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@graphql-toolkit/file-loading/-/file-loading-0.10.4.tgz", - "integrity": "sha512-oUmy/sO3BJfax85pVKI7FZ6TWrViNuWXoJkRM293YV9bKGuYU9TgqZoHyM+oEqWO5ruXCL/nCdw3cIBau+rSNA==", + "node_modules/@graphql-codegen/core/node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "globby": "11.0.0", - "unixify": "1.0.0" + "tslib": "^2.4.0" }, "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-toolkit/schema-merging": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@graphql-toolkit/schema-merging/-/schema-merging-0.10.4.tgz", - "integrity": "sha512-naL6reYBuILLMrkMfKz0lOLL0kl6gGYnaaywnO/Dgp9F4NeAxDdAs5CV6Fy9NO5OzePFP58Dnc4sh2RyYrrFJg==", + "node_modules/@graphql-codegen/core/node_modules/@graphql-tools/utils": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.0.tgz", + "integrity": "sha512-kaCwyWnURxMsYbxzkfylLqFFelu83jKk3BJOOy0GIuxEtgXVS9v7Y/tojljo69Q+jaZ2YxAi3+d8IpM+hx768A==", "dev": true, "dependencies": { - "@graphql-toolkit/common": "0.10.4", - "deepmerge": "4.2.2", - "graphql-tools": "5.0.0", - "tslib": "1.11.1" + "tslib": "^2.4.0" }, "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-toolkit/schema-merging/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/@graphql-codegen/plugin-helpers": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz", + "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@graphql-tools/utils": "^8.8.0", + "change-case-all": "1.0.14", + "common-tags": "1.8.2", + "import-from": "4.0.0", + "lodash": "~4.17.0", + "tslib": "~2.4.0" }, - "engines": { - "node": ">= 6" + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-toolkit/schema-merging/node_modules/graphql-tools": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-5.0.0.tgz", - "integrity": "sha512-5zn3vtn//382b7G3Wzz3d5q/sh+f7tVrnxeuhTMTJ7pWJijNqLxH7VEzv8VwXCq19zAzHYEosFHfXiK7qzvk7w==", - "deprecated": "This package has been deprecated and now it only exports makeExecutableSchema.\\nAnd it will no longer receive updates.\\nWe recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc.\\nCheck out https://www.graphql-tools.com to learn what package you should use instead", + "node_modules/@graphql-codegen/schema-ast": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.5.1.tgz", + "integrity": "sha512-tewa5DEKbglWn7kYyVBkh3J8YQ5ALqAMVmZwiVFIGOao5u66nd+e4HuFqp0u+Jpz4SJGGi0ap/oFrEvlqLjd2A==", "dev": true, "dependencies": { - "apollo-link": "^1.2.14", - "apollo-upload-client": "^13.0.0", - "deprecated-decorator": "^0.1.6", - "form-data": "^3.0.0", - "iterall": "^1.3.0", - "node-fetch": "^2.6.0", - "tslib": "^1.11.1", - "uuid": "^7.0.3" + "@graphql-codegen/plugin-helpers": "^2.6.2", + "@graphql-tools/utils": "^8.8.0", + "tslib": "~2.4.0" }, "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-toolkit/schema-merging/node_modules/tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true - }, - "node_modules/@graphql-toolkit/schema-merging/node_modules/uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "node_modules/@graphql-codegen/typescript": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.8.1.tgz", + "integrity": "sha512-kweV1DOOH2blvMheVL55TT0s9bxkmF/zijN9mdk9pRD20i/rI/46qbh8fNKqy/PV12vZOmZGNL6tigdghG2bqg==", "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "dependencies": { + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-codegen/schema-ast": "^2.5.1", + "@graphql-codegen/visitor-plugin-common": "2.13.1", + "auto-bind": "~4.0.0", + "tslib": "~2.4.0" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-tools/merge": { - "version": "6.2.17", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-6.2.17.tgz", - "integrity": "sha512-G5YrOew39fZf16VIrc49q3c8dBqQDD0ax5LYPiNja00xsXDi0T9zsEWVt06ApjtSdSF6HDddlu5S12QjeN8Tow==", + "node_modules/@graphql-codegen/typescript-resolvers": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-resolvers/-/typescript-resolvers-2.7.6.tgz", + "integrity": "sha512-z3wX3CV3MK7o52RAqbm0qXzAY9fPg0QLPArpdRYZ4AZ4sGAZQfGaQjyFcBJnY7pVB8KIEbBY7M4HNAqSmWH6+g==", "dev": true, "dependencies": { - "@graphql-tools/schema": "^8.0.2", - "@graphql-tools/utils": "8.0.2", - "tslib": "~2.3.0" + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-codegen/typescript": "^2.8.1", + "@graphql-codegen/visitor-plugin-common": "2.13.1", + "@graphql-tools/utils": "^8.8.0", + "auto-bind": "~4.0.0", + "tslib": "~2.4.0" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0" + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-tools/mock": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.6.3.tgz", - "integrity": "sha512-Nv095DXWz5Xt6U3SHhkIVtfuWyBNW1yiQk1o+DgM8/4Vj+v6zic1/y3eUpmoiy/qKu3qgagA6mxI8ZU/W6VS8w==", + "node_modules/@graphql-codegen/visitor-plugin-common": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.1.tgz", + "integrity": "sha512-mD9ufZhDGhyrSaWQGrU1Q1c5f01TeWtSWy/cDwXYjJcHIj1Y/DG2x0tOflEfCvh5WcnmHNIw4lzDsg1W7iFJEg==", + "dev": true, "dependencies": { - "@graphql-tools/schema": "8.3.5", - "@graphql-tools/utils": "8.6.5", - "fast-json-stable-stringify": "^2.1.0", - "tslib": "~2.3.0" + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-tools/optimize": "^1.3.0", + "@graphql-tools/relay-operation-optimizer": "^6.5.0", + "@graphql-tools/utils": "^8.8.0", + "auto-bind": "~4.0.0", + "change-case-all": "1.0.14", + "dependency-graph": "^0.11.0", + "graphql-tag": "^2.11.0", + "parse-filepath": "^1.0.2", + "tslib": "~2.4.0" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-tools/mock/node_modules/@graphql-tools/utils": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz", - "integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==", + "node_modules/@graphql-eslint/eslint-plugin": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@graphql-eslint/eslint-plugin/-/eslint-plugin-3.13.0.tgz", + "integrity": "sha512-ZFWqGrSU7GnKuNRQ0omlmLikHarQ3kUf4bd3OgFte/JnyHTDeHm5M1o5L32bnHQzuuMpSXEItLy8wqqKAlrGGg==", + "dev": true, "dependencies": { - "tslib": "~2.3.0" + "@babel/code-frame": "^7.18.6", + "@graphql-tools/code-file-loader": "^7.3.6", + "@graphql-tools/graphql-tag-pluck": "^7.3.6", + "@graphql-tools/utils": "^8.12.0", + "chalk": "^4.1.2", + "debug": "^4.3.4", + "fast-glob": "^3.2.12", + "graphql-config": "^4.3.6", + "graphql-depth-limit": "^1.1.0", + "lodash.lowercase": "^4.3.0" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/@graphql-tools/schema": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.5.tgz", - "integrity": "sha512-3mJ/K7TdL+fnEUtCUqF4qkh1fcNMzaxgwKgO9fSYSTS7zyT16hbi5XSulSTshygHgaD2u+MO588iR4ZJcbZcIg==", + "node_modules/@graphql-tools/apollo-engine-loader": { + "version": "7.3.17", + "resolved": "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.3.17.tgz", + "integrity": "sha512-h8rSDQDjtSElYc1vWZPIx6ZWMozSFyIN9hfGSY8kHIESU9O0ShEzs1lzRhmMmaAO75e7GxNwAjrBv/OCrxpETg==", + "dev": true, "dependencies": { - "@graphql-tools/merge": "8.2.6", - "@graphql-tools/utils": "8.6.5", - "tslib": "~2.3.0", - "value-or-promise": "1.0.11" + "@ardatan/sync-fetch": "0.0.1", + "@graphql-tools/utils": "9.0.1", + "@whatwg-node/fetch": "^0.5.0", + "tslib": "^2.4.0" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/merge": { - "version": "8.2.6", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.6.tgz", - "integrity": "sha512-dkwTm4czMISi/Io47IVvq2Fl9q4TIGKpJ0VZjuXYdEFkECyH6A5uwxZfPVandZG+gQs8ocFFoa6RisiUJLZrJw==", + "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, "dependencies": { - "@graphql-tools/utils": "8.6.5", - "tslib": "~2.3.0" + "tslib": "^2.4.0" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz", - "integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==", + "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/fetch": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.5.1.tgz", + "integrity": "sha512-RBZS60EU6CbRJ370BVVKW4F9csZuGh0OQNrUDhJ0IaIFLsXsJorFCM2iwaDWZTAPMqxW1TmuVcVKJ3d/H1dV1g==", + "dev": true, + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.12.0", + "web-streams-polyfill": "^3.2.0" + } + }, + "node_modules/@graphql-tools/batch-execute": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-8.5.10.tgz", + "integrity": "sha512-f3b/UPvscQ4NaSmSQIeZPNFhpZ9xb3AftKKSn9NzsUp3vxz0d8tymBVn28f51oqiqN9BMDpCH9P8TZrKpH1//Q==", + "dev": true, "dependencies": { - "tslib": "~2.3.0" + "@graphql-tools/utils": "9.0.1", + "dataloader": "2.1.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/utils": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.0.2.tgz", - "integrity": "sha512-gzkavMOgbhnwkHJYg32Adv6f+LxjbQmmbdD5Hty0+CWxvaiuJq+nU6tzb/7VSU4cwhbNLx/lGu2jbCPEW1McZQ==", + "node_modules/@graphql-tools/batch-execute/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "tslib": "~2.3.0" + "tslib": "^2.4.0" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0" + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@grpc/grpc-js": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz", - "integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==", - "optional": true, + "node_modules/@graphql-tools/code-file-loader": { + "version": "7.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-7.3.10.tgz", + "integrity": "sha512-UbEbuzhL01CvNhlesWMAo2ffRoyPRffTDlnUnkyvb6RuJkZhgY5A0k1RJYjt1uJQOkzPQLkkVKdSYqhHRkoH7g==", + "dev": true, "dependencies": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" + "@graphql-tools/graphql-tag-pluck": "7.3.10", + "@graphql-tools/utils": "9.0.1", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" }, - "engines": { - "node": "^8.13.0 || >=10.10.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@grpc/proto-loader": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", - "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", - "optional": true, + "node_modules/@graphql-tools/code-file-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, "dependencies": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.11.3", - "yargs": "^16.2.0" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + "tslib": "^2.4.0" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "node_modules/@graphql-tools/delegate": { + "version": "9.0.14", + "resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-9.0.14.tgz", + "integrity": "sha512-yKwNQl10fOdKxSk5yBoKnSjq1oumf4QYVinV9niD9KVow6j0dONtaiAYvhzaQwN/Xwwi7oADFACmKRtphlhFTw==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@graphql-tools/batch-execute": "8.5.10", + "@graphql-tools/executor": "0.0.6", + "@graphql-tools/schema": "9.0.8", + "@graphql-tools/utils": "9.0.1", + "dataloader": "2.1.0", + "tslib": "~2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": ">=10.10.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@graphql-tools/delegate/node_modules/@graphql-tools/merge": { + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", "dev": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@graphql-tools/delegate/node_modules/@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", "dev": true, "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@graphql-tools/delegate/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "tslib": "^2.4.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/@graphql-tools/executor": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-0.0.6.tgz", + "integrity": "sha512-2KIj1grRb1Lni97xgX1ryekcjU/WTMC1ZdPpnd0nYrBWs/C4Nv4UMNP7E/Tr8za8zlrsESvEUbpLHsBRiQsGxA==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "@graphql-tools/utils": "9.0.1", + "@graphql-typed-document-node/core": "3.1.1", + "@repeaterjs/repeater": "3.0.4", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/@graphql-tools/executor/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" + "tslib": "^2.4.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/@graphql-tools/git-loader": { + "version": "7.2.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-7.2.10.tgz", + "integrity": "sha512-y27w+7I5LmOXzz4EI3XHR+ZM2rZJquHnPAiEXLIt5Nh+9Z0frqtb4AJma3gAeRKROcKg5VN/Bx/ehp68S48lHw==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "@graphql-tools/graphql-tag-pluck": "7.3.10", + "@graphql-tools/utils": "9.0.1", + "is-glob": "4.0.3", + "micromatch": "^4.0.4", + "tslib": "^2.4.0", + "unixify": "^1.0.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/@graphql-tools/git-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/@graphql-tools/github-loader": { + "version": "7.3.17", + "resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-7.3.17.tgz", + "integrity": "sha512-JstgZUnifz2lQAk/mw7gq1uPSr5bG+7nw3IXZmUKOU+8zBjmFugRVWxLtJ1/bxZzqnhmYlC7nBqt1Ej1Tn5qKA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@ardatan/sync-fetch": "0.0.1", + "@graphql-tools/graphql-tag-pluck": "7.3.10", + "@graphql-tools/utils": "9.0.1", + "@whatwg-node/fetch": "^0.5.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@graphql-tools/github-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/fetch": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.5.1.tgz", + "integrity": "sha512-RBZS60EU6CbRJ370BVVKW4F9csZuGh0OQNrUDhJ0IaIFLsXsJorFCM2iwaDWZTAPMqxW1TmuVcVKJ3d/H1dV1g==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.12.0", + "web-streams-polyfill": "^3.2.0" } }, - "node_modules/@jest/console": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", - "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", + "node_modules/@graphql-tools/graphql-file-loader": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.5.9.tgz", + "integrity": "sha512-hEvWFLOG8JGsguWWdHqaFvj0xqwQu4KhqAKEjmIBq4vipVKLcmcjvOM56S0fv/dtn5pcKp9ZOZAxgncYVJ1hzw==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", - "slash": "^3.0.0" + "@graphql-tools/import": "6.7.10", + "@graphql-tools/utils": "9.0.1", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/core": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", - "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", + "node_modules/@graphql-tools/graphql-file-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "@jest/console": "^27.4.6", - "@jest/reporters": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.7", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-resolve-dependencies": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "jest-watcher": "^27.4.6", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "tslib": "^2.4.0" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/environment": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", - "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", + "node_modules/@graphql-tools/graphql-tag-pluck": { + "version": "7.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.3.10.tgz", + "integrity": "sha512-A3FHMbi90NHWTIzrwnbI0kHwCWfSL8j7zXuuIZKL009V+M8K0DPg/+ZCy/4SQB14yl/NTz5ZQ/0GXffD3qvMDg==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6" + "@babel/parser": "^7.16.8", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/fake-timers": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", - "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", + "node_modules/@graphql-tools/graphql-tag-pluck/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" + "tslib": "^2.4.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/globals": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", - "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", + "node_modules/@graphql-tools/import": { + "version": "6.7.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-6.7.10.tgz", + "integrity": "sha512-6L19Ep0pP5wWywq9/jwCt2FdCJnEnyrxkmRkSRdYoTEmOFz5xrsfhyUfWl8ibx34gWzVYhCDOX1bN43zsLCbDA==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/types": "^27.4.2", - "expect": "^27.4.6" + "@graphql-tools/utils": "9.0.1", + "resolve-from": "5.0.0", + "tslib": "^2.4.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/reporters": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", - "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", + "node_modules/@graphql-tools/import/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "tslib": "^2.4.0" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/source-map": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", - "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", + "node_modules/@graphql-tools/json-file-loader": { + "version": "7.4.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-7.4.10.tgz", + "integrity": "sha512-/njUvIW/zdSr70eWDfDQNDXp2UQLe+YKFRLMZkpuISrw5cdvGaMepwpr0Yz6kFnHGwB6wSYLH25LkRAzpiKz+g==", "dev": true, "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "@graphql-tools/utils": "9.0.1", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/test-result": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", - "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", + "node_modules/@graphql-tools/json-file-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "dependencies": { - "@jest/console": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "tslib": "^2.4.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", - "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", + "node_modules/@graphql-tools/load": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-7.8.0.tgz", + "integrity": "sha512-l4FGgqMW0VOqo+NMYizwV8Zh+KtvVqOf93uaLo9wJ3sS3y/egPCgxPMDJJ/ufQZG3oZ/0oWeKt68qop3jY0yZg==", "dev": true, "dependencies": { - "@jest/test-result": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-runtime": "^27.4.6" + "@graphql-tools/schema": "9.0.4", + "@graphql-tools/utils": "8.12.0", + "p-limit": "3.1.0", + "tslib": "^2.4.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/transform": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", - "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", + "node_modules/@graphql-tools/load/node_modules/@graphql-tools/merge": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.6.tgz", + "integrity": "sha512-uUBokxXi89bj08P+iCvQk3Vew4vcfL5ZM6NTylWi8PIpoq4r5nJ625bRuN8h2uubEdRiH8ntN9M4xkd/j7AybQ==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "@graphql-tools/utils": "8.12.0", + "tslib": "^2.4.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "node_modules/@graphql-tools/load/node_modules/@graphql-tools/schema": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.4.tgz", + "integrity": "sha512-B/b8ukjs18fq+/s7p97P8L1VMrwapYc3N2KvdG/uNThSazRRn8GsBK0Nr+FH+mVKiUfb4Dno79e3SumZVoHuOQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" + "@graphql-tools/merge": "8.3.6", + "@graphql-tools/utils": "8.12.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@josephg/resolvable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", - "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@graphql-tools/load/node_modules/@graphql-tools/utils": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.12.0.tgz", + "integrity": "sha512-TeO+MJWGXjUTS52qfK4R8HiPoF/R7X+qmgtOYd8DTH0l6b+5Y/tlg5aGeUJefqImRq7nvi93Ms40k/Uz4D5CWw==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "tslib": "^2.4.0" }, - "engines": { - "node": ">= 8" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" + "node_modules/@graphql-tools/merge": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz", + "integrity": "sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg==", + "dependencies": { + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "tslib": "^2.4.0" }, - "engines": { - "node": ">= 8" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@opencensus/core": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz", - "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==", + "node_modules/@graphql-tools/mock": { + "version": "8.7.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.7.10.tgz", + "integrity": "sha512-PuRGfk6TQger7EfE08yO3+QCAcZ6nYo3kyoEmTPc27w4yiqKCwZIyD8vegzl/EQphEourjaOhO149te6qNEUeQ==", "dependencies": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^5.5.0", - "shimmer": "^1.2.0", - "uuid": "^3.2.1" + "@graphql-tools/schema": "9.0.8", + "@graphql-tools/utils": "9.0.1", + "fast-json-stable-stringify": "^2.1.0", + "tslib": "^2.4.0" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@opencensus/propagation-b3": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz", - "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==", + "node_modules/@graphql-tools/mock/node_modules/@graphql-tools/merge": { + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", "dependencies": { - "@opencensus/core": "^0.0.8", - "uuid": "^3.2.1" + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@opencensus/propagation-b3/node_modules/@opencensus/core": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz", - "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==", + "node_modules/@graphql-tools/mock/node_modules/@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", "dependencies": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^5.5.0", - "shimmer": "^1.2.0", - "uuid": "^3.2.1" + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@panva/asn1.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", - "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", - "engines": { - "node": ">=10.13.0" + "node_modules/@graphql-tools/mock/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/agent": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.1.tgz", - "integrity": "sha512-QKHMm6yexcvdDfcNE7PL9D6uEjoQPGRi+8dh+rc4Hwtbpsbh5IAvZbz3BVGjcd4HaX6pt2xGpOohG7/Y2L4QLw==", + "node_modules/@graphql-tools/optimize": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.3.1.tgz", + "integrity": "sha512-5j5CZSRGWVobt4bgRRg7zhjPiSimk+/zIuColih8E8DxuFOaJ+t0qu7eZS5KXWBkjcd4BPNuhUPpNlEmHPqVRQ==", + "dev": true, "dependencies": { - "async": "~3.2.0", - "chalk": "~3.0.0", - "dayjs": "~1.8.24", - "debug": "~4.3.1", - "eventemitter2": "~5.0.1", - "fast-json-patch": "^3.0.0-1", - "fclone": "~1.0.11", - "nssocket": "0.6.0", - "pm2-axon": "~4.0.1", - "pm2-axon-rpc": "~0.7.0", - "proxy-agent": "~5.0.0", - "semver": "~7.2.0", - "ws": "~7.4.0" + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/agent/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/@graphql-tools/prisma-loader": { + "version": "7.2.30", + "resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-7.2.30.tgz", + "integrity": "sha512-EmYC6ltX2TxOKPgiqdVZctm3uyXdwo53GBwWNyOTIx+8hczrF9LO59LGwNtuy+GsT5A1ZK93og7F+8zztkCFIw==", + "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@graphql-tools/url-loader": "7.16.10", + "@graphql-tools/utils": "9.0.1", + "@types/js-yaml": "^4.0.0", + "@types/json-stable-stringify": "^1.0.32", + "@types/jsonwebtoken": "^8.5.0", + "chalk": "^4.1.0", + "debug": "^4.3.1", + "dotenv": "^16.0.0", + "graphql-request": "^5.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "isomorphic-fetch": "^3.0.0", + "js-yaml": "^4.0.0", + "json-stable-stringify": "^1.0.1", + "jsonwebtoken": "^8.5.1", + "lodash": "^4.17.20", + "scuid": "^1.1.0", + "tslib": "^2.4.0", + "yaml-ast-parser": "^0.0.43" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@graphql-tools/prisma-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, "dependencies": { - "ms": "2.1.2" + "tslib": "^2.4.0" }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/@pm2/agent/node_modules/semver": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz", - "integrity": "sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig==", - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/@graphql-tools/prisma-loader/node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/@pm2/agent/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "engines": { - "node": ">=8.3.0" + "node_modules/@graphql-tools/relay-operation-optimizer": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.5.10.tgz", + "integrity": "sha512-daNJRkJa/NgpXVxUApCMIGqHoyHExaG7XN2gk48r+DbKmoahpflF+lnhBKmS44HtSGciFUv8bPbp0NWvXafZ2w==", + "dev": true, + "dependencies": { + "@ardatan/relay-compiler": "12.0.0", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" }, "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/io": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@pm2/io/-/io-5.0.0.tgz", - "integrity": "sha512-3rToDVJaRoob5Lq8+7Q2TZFruoEkdORxwzFpZaqF4bmH6Bkd7kAbdPrI/z8X6k1Meq5rTtScM7MmDgppH6aLlw==", + "node_modules/@graphql-tools/relay-operation-optimizer/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, "dependencies": { - "@opencensus/core": "0.0.9", - "@opencensus/propagation-b3": "0.0.8", - "async": "~2.6.1", - "debug": "~4.3.1", - "eventemitter2": "^6.3.1", - "require-in-the-middle": "^5.0.0", - "semver": "6.3.0", - "shimmer": "^1.2.0", - "signal-exit": "^3.0.3", - "tslib": "1.9.3" + "tslib": "^2.4.0" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/io/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "node_modules/@graphql-tools/schema": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz", + "integrity": "sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==", "dependencies": { - "lodash": "^4.17.14" + "@graphql-tools/merge": "8.3.1", + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/io/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", "dependencies": { - "ms": "2.1.2" + "tslib": "^2.4.0" }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/io/node_modules/eventemitter2": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", - "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" + "node_modules/@graphql-tools/url-loader": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-7.16.10.tgz", + "integrity": "sha512-VFf0lKZpPSFtUl3cNycBEWlB8NzJhXFfas0PYsFmzzOmtGcHeY3rY2KMUfBr4wq7chPfBbGpcuAwjiI3x9MZzg==", + "dev": true, + "dependencies": { + "@ardatan/sync-fetch": "0.0.1", + "@graphql-tools/delegate": "9.0.14", + "@graphql-tools/utils": "9.0.1", + "@graphql-tools/wrap": "9.2.9", + "@types/ws": "^8.0.0", + "@whatwg-node/fetch": "^0.5.0", + "dset": "^3.1.2", + "extract-files": "^11.0.0", + "graphql-ws": "^5.4.1", + "isomorphic-ws": "^5.0.0", + "meros": "^1.1.4", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.11", + "ws": "^8.3.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } }, - "node_modules/@pm2/io/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/@graphql-tools/url-loader/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } }, - "node_modules/@pm2/io/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" + "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/fetch": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.5.1.tgz", + "integrity": "sha512-RBZS60EU6CbRJ370BVVKW4F9csZuGh0OQNrUDhJ0IaIFLsXsJorFCM2iwaDWZTAPMqxW1TmuVcVKJ3d/H1dV1g==", + "dev": true, + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.12.0", + "web-streams-polyfill": "^3.2.0" } }, - "node_modules/@pm2/io/node_modules/tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + "node_modules/@graphql-tools/utils": { + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz", + "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } }, - "node_modules/@pm2/js-api": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz", - "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==", + "node_modules/@graphql-tools/wrap": { + "version": "9.2.9", + "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-9.2.9.tgz", + "integrity": "sha512-GiEMy7VJIKxdgb9E8ZkaAPhePsDbBP5rOj07tr6jzcDY+ZhLcjmD9UuiPGVFgBSu6AzRyoviEJgI0hjksqfl1A==", + "dev": true, "dependencies": { - "async": "^2.6.3", - "axios": "^0.21.0", - "debug": "~4.3.1", - "eventemitter2": "^6.3.1", - "ws": "^7.0.0" + "@graphql-tools/delegate": "9.0.14", + "@graphql-tools/schema": "9.0.8", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": ">=4.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/js-api/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "node_modules/@graphql-tools/wrap/node_modules/@graphql-tools/merge": { + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", + "dev": true, "dependencies": { - "lodash": "^4.17.14" + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/js-api/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@graphql-tools/wrap/node_modules/@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", + "dev": true, "dependencies": { - "ms": "2.1.2" + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/wrap/node_modules/@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@pm2/js-api/node_modules/eventemitter2": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", - "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" + "node_modules/@graphql-typed-document-node/core": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz", + "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==", + "dev": true, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } }, - "node_modules/@pm2/js-api/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/@grpc/grpc-js": { + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.12.tgz", + "integrity": "sha512-JmvQ03OTSpVd9JTlj/K3IWHSz4Gk/JMLUTtW7Zb0KvO1LcOYGATh5cNuRYzCAeDR3O8wq+q8FZe97eO9MBrkUw==", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.0", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.3.tgz", + "integrity": "sha512-5dAvoZwna2Py3Ef96Ux9jIkp3iZ62TUsV00p3wVBPNX5K178UbNi8Q7gQVqwXT1Yq9RejIGG9G2IPEo93T6RcA==", + "optional": true, "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^7.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" } }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "node_modules/@grpc/grpc-js/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "node_modules/@grpc/grpc-js/node_modules/protobufjs": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.1.2.tgz", + "integrity": "sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "node_modules/@grpc/grpc-js/node_modules/protobufjs/node_modules/long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==", + "optional": true }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "node_modules/@grpc/grpc-js/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "optional": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, + "node_modules/@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "optional": true, + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, "engines": { "node": ">=6" } }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "optional": true, "dependencies": { - "type-detect": "4.0.8" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "optional": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", "dev": true, "dependencies": { - "defer-to-connect": "^1.0.1" + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" }, "engines": { - "node": ">=6" + "node": ">=10.10.0" } }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/@types/accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "node_modules/@josephg/resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", + "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, "dependencies": { - "@types/node": "*" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/babel__core": { - "version": "7.1.18", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", - "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/bson": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", - "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "dependencies": { - "@types/node": "*" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "node_modules/@opencensus/core": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz", + "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==", "dependencies": { - "@types/node": "*" + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + }, + "engines": { + "node": ">=6.0" } }, - "node_modules/@types/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==" - }, - "node_modules/@types/cookies": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz", - "integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==", - "dependencies": { - "@types/connect": "*", - "@types/express": "*", - "@types/keygrip": "*", - "@types/node": "*" + "node_modules/@opencensus/core/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" } }, - "node_modules/@types/cors": { - "version": "2.8.10", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", - "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==" - }, - "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "node_modules/@opencensus/propagation-b3": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz", + "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==", "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" + "@opencensus/core": "^0.0.8", + "uuid": "^3.2.1" + }, + "engines": { + "node": ">=6.0" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "node_modules/@opencensus/propagation-b3/node_modules/@opencensus/core": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz", + "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + }, + "engines": { + "node": ">=6.0" } }, - "node_modules/@types/fs-capacitor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz", - "integrity": "sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ==", - "dependencies": { - "@types/node": "*" + "node_modules/@opencensus/propagation-b3/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "dependencies": { - "@types/node": "*" + "node_modules/@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", + "engines": { + "node": ">=10.13.0" } }, - "node_modules/@types/http-assert": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz", - "integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==" - }, - "node_modules/@types/http-errors": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.2.tgz", - "integrity": "sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "node_modules/@peculiar/asn1-schema": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.0.tgz", + "integrity": "sha512-DtNLAG4vmDrdSJFPe7rypkcj597chNQL7u+2dBtYo5mh7VW2+im6ke+O0NVr8W1f4re4C3F71LhoMb0Yxqa48Q==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*" + "asn1js": "^3.0.5", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "node_modules/@types/jsonwebtoken": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz", - "integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==", + "node_modules/@peculiar/webcrypto": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.1.tgz", + "integrity": "sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==", + "dev": true, "dependencies": { - "@types/node": "*" + "@peculiar/asn1-schema": "^2.3.0", + "@peculiar/json-schema": "^1.1.12", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.1", + "webcrypto-core": "^1.7.4" + }, + "engines": { + "node": ">=10.12.0" } }, - "node_modules/@types/keygrip": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", - "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==" - }, - "node_modules/@types/koa": { - "version": "2.13.4", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.4.tgz", - "integrity": "sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw==", + "node_modules/@pm2/agent": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.1.tgz", + "integrity": "sha512-QKHMm6yexcvdDfcNE7PL9D6uEjoQPGRi+8dh+rc4Hwtbpsbh5IAvZbz3BVGjcd4HaX6pt2xGpOohG7/Y2L4QLw==", "dependencies": { - "@types/accepts": "*", - "@types/content-disposition": "*", - "@types/cookies": "*", - "@types/http-assert": "*", - "@types/http-errors": "*", - "@types/keygrip": "*", - "@types/koa-compose": "*", - "@types/node": "*" + "async": "~3.2.0", + "chalk": "~3.0.0", + "dayjs": "~1.8.24", + "debug": "~4.3.1", + "eventemitter2": "~5.0.1", + "fast-json-patch": "^3.0.0-1", + "fclone": "~1.0.11", + "nssocket": "0.6.0", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.0", + "proxy-agent": "~5.0.0", + "semver": "~7.2.0", + "ws": "~7.4.0" } }, - "node_modules/@types/koa-compose": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", - "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", + "node_modules/@pm2/agent/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dependencies": { - "@types/koa": "*" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "node_modules/@pm2/agent/node_modules/dayjs": { + "version": "1.8.36", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", + "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" }, - "node_modules/@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", - "dependencies": { - "@types/bson": "*", - "@types/node": "*" + "node_modules/@pm2/agent/node_modules/semver": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz", + "integrity": "sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@types/node": { - "version": "17.0.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.14.tgz", - "integrity": "sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng==" - }, - "node_modules/@types/prettier": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", - "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" + "node_modules/@pm2/agent/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "node_modules/@pm2/io": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@pm2/io/-/io-5.0.0.tgz", + "integrity": "sha512-3rToDVJaRoob5Lq8+7Q2TZFruoEkdORxwzFpZaqF4bmH6Bkd7kAbdPrI/z8X6k1Meq5rTtScM7MmDgppH6aLlw==", "dependencies": { - "@types/node": "*" + "@opencensus/core": "0.0.9", + "@opencensus/propagation-b3": "0.0.8", + "async": "~2.6.1", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "require-in-the-middle": "^5.0.0", + "semver": "6.3.0", + "shimmer": "^1.2.0", + "signal-exit": "^3.0.3", + "tslib": "1.9.3" + }, + "engines": { + "node": ">=6.0" } }, - "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, + "node_modules/@pm2/io/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dependencies": { - "@types/yargs-parser": "*" + "lodash": "^4.17.14" } }, - "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true + "node_modules/@pm2/io/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, + "node_modules/@pm2/io/node_modules/tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, + "node_modules/@pm2/js-api": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz", + "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==", "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "async": "^2.6.3", + "axios": "^0.21.0", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "ws": "^7.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "node": ">=4.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, + "node_modules/@pm2/js-api/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "lodash": "^4.17.14" } }, - "node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "node_modules/@pm2/js-api/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, + "node_modules/@pm2/js-api/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=8.3.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { - "typescript": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { "optional": true } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, + "node_modules/@pm2/pm2-version-check": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", + "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "debug": "^4.3.1" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@repeaterjs/repeater": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", + "integrity": "sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==", "dev": true }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "devOptional": true, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">= 10" } }, - "node_modules/@wry/equality": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz", - "integrity": "sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==", - "dependencies": { - "tslib": "^1.9.3" - } + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true }, - "node_modules/@wry/equality/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "optional": true, + "node_modules/@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" + "@types/node": "*" } }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "node_modules/@types/bcryptjs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", + "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "node_modules/@types/bson": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", + "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", + "dependencies": { + "@types/node": "*" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "node_modules/@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", + "dev": true + }, + "node_modules/@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" + "@types/chai": "*" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/@types/cls-hooked": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/cls-hooked/-/cls-hooked-4.3.3.tgz", + "integrity": "sha512-gNstDTb/ty5h6gJd6YpSPgsLX9LmRpaKJqGFp7MRlYxhwp4vXXKlJ9+bt1TZ9KbVNXE+Mbxy2AYXcpY21DDtJw==", "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "@types/node": "*" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } + "node_modules/@types/content-disposition": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz", + "integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==" }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@types/cookies": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz", + "integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==", "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" } }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/@types/copy-paste": { + "version": "1.1.30", + "resolved": "https://registry.npmjs.org/@types/copy-paste/-/copy-paste-1.1.30.tgz", + "integrity": "sha512-/pjP3jEYc+JFXjNMjlJaSE7ZVpPYCUz0+jdF1nVzFOsEygxTt0Jr9k3DbfKV3CDfZLjFpJ5p/B+vNLxWVe9Cvw==", + "dev": true }, - "node_modules/aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "dev": true, + "node_modules/@types/cors": { + "version": "2.8.10", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", + "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==" + }, + "node_modules/@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@types/express-rate-limit": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/express-rate-limit/-/express-rate-limit-5.1.3.tgz", + "integrity": "sha512-H+TYy3K53uPU2TqPGFYaiWc2xJV6+bIFkDd/Ma2/h67Pa6ARk9kWE0p/K9OH1Okm0et9Sfm66fmXoAxsH2PHXg==", + "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "@types/express": "*" } }, - "node_modules/amp": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", - "integrity": "sha1-at+NWKdPNh6CwfqNOJwHnhOfxH0=" - }, - "node_modules/amp-message": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", - "integrity": "sha1-p48cmJlQh602GSpBKY5NtJ49/EU=", + "node_modules/@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", "dependencies": { - "amp": "0.3.1" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "node_modules/@types/fs-capacitor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz", + "integrity": "sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ==", "dependencies": { - "string-width": "^4.1.0" + "@types/node": "*" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "engines": { - "node": ">=6" + "node_modules/@types/graphql-depth-limit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/graphql-depth-limit/-/graphql-depth-limit-1.1.3.tgz", + "integrity": "sha512-fvK0qXNvwKD5bSnMEkidi51EloYsz/E8JG/8Kzq1peoLRQAEGgLVauE1xGeT4W/nbSpecgG+34dcKPdwfGzFHQ==", + "dev": true, + "dependencies": { + "graphql": "^14.5.3" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@types/graphql-depth-limit/node_modules/graphql": { + "version": "14.7.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", + "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", + "dev": true, "dependencies": { - "type-fest": "^0.21.3" + "iterall": "^1.2.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6.x" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/@types/http-assert": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz", + "integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==" }, - "node_modules/ansi-font": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ansi-font/-/ansi-font-0.0.2.tgz", - "integrity": "sha1-iQMBvVhBRi/TnAt3Ca/R9SUUMzE=", - "engines": { - "node": ">=0.4.x" - } + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==" }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" + "node_modules/@types/i18n": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/@types/i18n/-/i18n-0.13.5.tgz", + "integrity": "sha512-pEtMt7iBkPBFMcB4TG6NuJIz/3Osp530o3R/3Qci94d59J4ienHyWnC7/AKUoTWqqnK0nG6gd6I2g8aOGdlwIg==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/js-yaml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", + "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/json-stable-stringify": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz", + "integrity": "sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw==", + "dev": true + }, + "node_modules/@types/jsonwebtoken": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", + "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", + "dependencies": { + "@types/node": "*" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@types/keygrip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", + "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==" + }, + "node_modules/@types/koa": { + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.5.tgz", + "integrity": "sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@types/accepts": "*", + "@types/content-disposition": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/http-errors": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" } }, - "node_modules/ansi-styles/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@types/koa-compose": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", + "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/koa": "*" } }, - "node_modules/ansi-styles/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "node_modules/@types/lodash": { + "version": "4.14.187", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.187.tgz", + "integrity": "sha512-MrO/xLXCaUgZy3y96C/iOsaIqZSeupyTImKClHunL5GrmaiII2VwvWmLBu2hwa0Kp0sV19CsyjtrTc/Fx8rg/A==", + "dev": true }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, - "node_modules/apollo-cache-control": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.14.0.tgz", - "integrity": "sha512-qN4BCq90egQrgNnTRMUHikLZZAprf3gbm8rC5Vwmc6ZdLolQ7bFsa769Hqi6Tq/lS31KLsXBLTOsRbfPHph12w==", - "deprecated": "The functionality provided by the `apollo-cache-control` package is built in to `apollo-server-core` starting with Apollo Server 3. See https://www.apollographql.com/docs/apollo-server/migration/#cachecontrol for details.", + "node_modules/@types/mongodb": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", + "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", "dependencies": { - "apollo-server-env": "^3.1.0", - "apollo-server-plugin-base": "^0.13.0" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "@types/bson": "*", + "@types/node": "*" } }, - "node_modules/apollo-cache-control/node_modules/apollo-server-plugin-base": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz", - "integrity": "sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg==", + "node_modules/@types/mongoose-paginate-v2": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@types/mongoose-paginate-v2/-/mongoose-paginate-v2-1.6.5.tgz", + "integrity": "sha512-OdnsqewLwCtZvExUHuL+KDVlZ6OdnzGcUdPpEqMRVKZ6mWy7fgnt1IkLSs8Zugv5cUTLVT46hjmL2OPWtml1Rw==", + "deprecated": "This is a stub types definition. mongoose-paginate-v2 provides its own type definitions, so you do not need this installed.", + "dev": true, "dependencies": { - "apollo-server-types": "^0.9.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "mongoose-paginate-v2": "*" } }, - "node_modules/apollo-datasource": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-3.3.2.tgz", - "integrity": "sha512-L5TiS8E2Hn/Yz7SSnWIVbZw0ZfEIXZCa5VUiVxD9P53JvSrf4aStvsFDlGWPvpIdCR+aly2CfoB79B9/JjKFqg==", + "node_modules/@types/morgan": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz", + "integrity": "sha512-BiLcfVqGBZCyNCnCH3F4o2GmDLrpy0HeBVnNlyZG4fo88ZiE9SoiBe3C+2ezuwbjlEyT+PDZ17//TAlRxAn75Q==", + "dev": true, "dependencies": { - "@apollo/utils.keyvaluecache": "^1.0.1", - "apollo-server-env": "^4.2.1" - }, - "engines": { - "node": ">=12.0" + "@types/node": "*" } }, - "node_modules/apollo-datasource/node_modules/apollo-server-env": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", - "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + }, + "node_modules/@types/nodemailer": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.6.tgz", + "integrity": "sha512-pD6fL5GQtUKvD2WnPmg5bC2e8kWCAPDwMPmHe/ohQbW+Dy0EcHgZ2oCSuPlWNqk74LS5BVMig1SymQbFMPPK3w==", + "dev": true, "dependencies": { - "node-fetch": "^2.6.7" - }, - "engines": { - "node": ">=12.0" + "@types/node": "*" } }, - "node_modules/apollo-graphql": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.5.tgz", - "integrity": "sha512-RGt5k2JeBqrmnwRM0VOgWFiGKlGJMfmiif/4JvdaEqhMJ+xqe/9cfDYzXfn33ke2eWixsAbjEbRfy8XbaN9nTw==", - "dependencies": { - "core-js-pure": "^3.10.2", - "lodash.sortby": "^4.7.0", - "sha.js": "^2.4.11" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "graphql": "^14.2.1 || ^15.0.0" - } + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true }, - "node_modules/apollo-link": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz", - "integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==", - "dependencies": { - "apollo-utilities": "^1.3.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3", - "zen-observable-ts": "^0.8.21" - }, - "peerDependencies": { - "graphql": "^0.11.3 || ^0.12.3 || ^0.13.0 || ^14.0.0 || ^15.0.0" - } + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, - "node_modules/apollo-link-http-common": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz", - "integrity": "sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==", - "dev": true, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", "dependencies": { - "apollo-link": "^1.2.14", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3" - }, - "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "@types/mime": "*", + "@types/node": "*" } }, - "node_modules/apollo-link-http-common/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "node_modules/@types/shortid": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/shortid/-/shortid-0.0.29.tgz", + "integrity": "sha512-9BCYD9btg2CY4kPcpMQ+vCR8U6V8f/KvixYD5ZbxoWlkhddNF5IeZMVL3p+QFUkg+Hb+kPAG9Jgk4bnnF1v/Fw==", "dev": true }, - "node_modules/apollo-link/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@types/uuid": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", + "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==", + "dev": true }, - "node_modules/apollo-reporting-protobuf": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", - "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", + "node_modules/@types/validator": { + "version": "13.7.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.10.tgz", + "integrity": "sha512-t1yxFAR2n0+VO6hd/FJ9F2uezAZVWHLmpmlJzm1eX03+H7+HsuTAp7L8QJs+2pQCfWkP1+EXsGK9Z9v7o/qPVQ==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dev": true, "dependencies": { - "@apollo/protobufjs": "1.2.2" + "@types/node": "*" } }, - "node_modules/apollo-server-caching": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.7.0.tgz", - "integrity": "sha512-MsVCuf/2FxuTFVhGLK13B+TZH9tBd2qkyoXKKILIiGcZ5CDUEBO14vIV63aNkMkS1xxvK2U4wBcuuNj/VH2Mkw==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.0.tgz", + "integrity": "sha512-5TJh2AgL6+wpL8H/GTSjNb4WrjKoR2rqvFxR/DDTqYNk6uXn8BJMEcncLSpMbf/XV1aS0jAjYwn98uvVCiAywQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.42.0", + "@typescript-eslint/type-utils": "5.42.0", + "@typescript-eslint/utils": "5.42.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/apollo-server-core": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.10.1.tgz", - "integrity": "sha512-UFFziv6h15QbKRZOA6wLyr1Sle9kns3JuQ5DEB7OYe5AIoOJNjZkWXX/tmLFUrSmlnDDryi6Sf5pDzpYmUC/UA==", + "node_modules/@typescript-eslint/parser": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.0.tgz", + "integrity": "sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA==", + "dev": true, "dependencies": { - "@apollo/utils.keyvaluecache": "^1.0.1", - "@apollo/utils.logger": "^1.0.0", - "@apollo/utils.usagereporting": "^1.0.0", - "@apollographql/apollo-tools": "^0.5.3", - "@apollographql/graphql-playground-html": "1.6.29", - "@graphql-tools/mock": "^8.1.2", - "@graphql-tools/schema": "^8.0.0", - "@josephg/resolvable": "^1.0.0", - "apollo-datasource": "^3.3.2", - "apollo-reporting-protobuf": "^3.3.2", - "apollo-server-env": "^4.2.1", - "apollo-server-errors": "^3.3.1", - "apollo-server-plugin-base": "^3.6.2", - "apollo-server-types": "^3.6.2", - "async-retry": "^1.2.1", - "fast-json-stable-stringify": "^2.1.0", - "graphql-tag": "^2.11.0", - "loglevel": "^1.6.8", - "lru-cache": "^6.0.0", - "sha.js": "^2.4.11", - "uuid": "^8.0.0", - "whatwg-mimetype": "^3.0.0" + "@typescript-eslint/scope-manager": "5.42.0", + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/typescript-estree": "5.42.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=12.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "graphql": "^15.3.0 || ^16.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-server-core/node_modules/@apollo/protobufjs": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.4.tgz", - "integrity": "sha512-npVJ9NVU/pynj+SCU+fambvTneJDyCnif738DnZ7pCxdDtzeEz7WkpSIq5wNUmWm5Td55N+S2xfqZ+WP4hDLng==", - "hasInstallScript": true, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.0.tgz", + "integrity": "sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==", + "dev": true, "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/visitor-keys": "5.42.0" }, - "bin": { - "apollo-pbjs": "bin/pbjs", - "apollo-pbts": "bin/pbts" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-server-core/node_modules/@apollographql/graphql-playground-html": { - "version": "1.6.29", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz", - "integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.0.tgz", + "integrity": "sha512-HW14TXC45dFVZxnVW8rnUGnvYyRC0E/vxXShFCthcC9VhVTmjqOmtqj6H5rm9Zxv+ORxKA/1aLGD7vmlLsdlOg==", + "dev": true, "dependencies": { - "xss": "^1.0.8" + "@typescript-eslint/typescript-estree": "5.42.0", + "@typescript-eslint/utils": "5.42.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-server-core/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + "node_modules/@typescript-eslint/types": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.0.tgz", + "integrity": "sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, - "node_modules/apollo-server-core/node_modules/apollo-reporting-protobuf": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.2.tgz", - "integrity": "sha512-j1tx9tmkVdsLt1UPzBrvz90PdjAeKW157WxGn+aXlnnGfVjZLIRXX3x5t1NWtXvB7rVaAsLLILLtDHW382TSoQ==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.0.tgz", + "integrity": "sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==", + "dev": true, "dependencies": { - "@apollo/protobufjs": "1.2.4" + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/visitor-keys": "5.42.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/apollo-server-core/node_modules/apollo-server-env": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", - "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, "dependencies": { - "node-fetch": "^2.6.7" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=12.0" + "node": ">=10" } }, - "node_modules/apollo-server-core/node_modules/apollo-server-types": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.6.2.tgz", - "integrity": "sha512-9Z54S7NB+qW1VV+kmiqwU2Q6jxWfX89HlSGCGOo3zrkrperh85LrzABgN9S92+qyeHYd72noMDg2aI039sF3dg==", + "node_modules/@typescript-eslint/utils": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.0.tgz", + "integrity": "sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==", + "dev": true, "dependencies": { - "@apollo/utils.keyvaluecache": "^1.0.1", - "@apollo/utils.logger": "^1.0.0", - "apollo-reporting-protobuf": "^3.3.2", - "apollo-server-env": "^4.2.1" + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.42.0", + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/typescript-estree": "5.42.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, "engines": { - "node": ">=12.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "graphql": "^15.3.0 || ^16.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/apollo-server-core/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { - "uuid": "dist/bin/uuid" + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/apollo-server-core/node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.0.tgz", + "integrity": "sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.42.0", + "eslint-visitor-keys": "^3.3.0" + }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/apollo-server-env": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.1.0.tgz", - "integrity": "sha512-iGdZgEOAuVop3vb0F2J3+kaBVi4caMoxefHosxmgzAbbSpvWehB8Y1QiSyyMeouYC38XNVk5wnZl+jdGSsWsIQ==", + "node_modules/@vitest/coverage-c8": { + "version": "0.24.5", + "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.24.5.tgz", + "integrity": "sha512-955yK/SdSBZPYrSXgXB0F+0JnOX5EY9kSL7ywJ4rNajmkFUhwLjuKm13Xb6YKSyIY/g5WvbBnyowqfNRxBJ3ww==", + "dev": true, "dependencies": { - "node-fetch": "^2.6.1", - "util.promisify": "^1.0.0" + "c8": "^7.12.0", + "vitest": "0.24.5" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/apollo-server-errors": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-3.3.1.tgz", - "integrity": "sha512-xnZJ5QWs6FixHICXHxUfm+ZWqqxrNuPlQ+kj5m6RtEgIpekOPssH/SD9gf2B4HuWV0QozorrygwZnux8POvyPA==", - "engines": { - "node": ">=12.0" + "node_modules/@whatwg-node/fetch": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.3.2.tgz", + "integrity": "sha512-Bs5zAWQs0tXsLa4mRmLw7Psps1EN78vPtgcLpw3qPY8s6UYPUM67zFZ9cy+7tZ64PXhfwzxJn+m7RH2Lq48RNQ==", + "dev": true, + "dependencies": { + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "event-target-polyfill": "^0.0.3", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.8.0", + "web-streams-polyfill": "^3.2.0" + } + }, + "node_modules/@wry/equality": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz", + "integrity": "sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==", + "dependencies": { + "tslib": "^1.9.3" + } + }, + "node_modules/@wry/equality/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "devOptional": true, + "dependencies": { + "event-target-shim": "^5.0.0" }, - "peerDependencies": { - "graphql": "^15.3.0 || ^16.0.0" + "engines": { + "node": ">=6.5" } }, - "node_modules/apollo-server-express": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.25.3.tgz", - "integrity": "sha512-tTFYn0oKH2qqLwVj7Ez2+MiKleXACODiGh5IxsB7VuYCPMAi9Yl8iUSlwTjQUvgCWfReZjnf0vFL2k5YhDlrtQ==", + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { - "@apollographql/graphql-playground-html": "1.6.27", - "@types/accepts": "^1.3.5", - "@types/body-parser": "1.19.0", - "@types/cors": "2.8.10", - "@types/express": "^4.17.12", - "@types/express-serve-static-core": "^4.17.21", - "accepts": "^1.3.5", - "apollo-server-core": "^2.25.3", - "apollo-server-types": "^0.9.0", - "body-parser": "^1.18.3", - "cors": "^2.8.5", - "express": "^4.17.1", - "graphql-subscriptions": "^1.0.0", - "graphql-tools": "^4.0.8", - "parseurl": "^1.3.2", - "subscriptions-transport-ws": "^0.9.19", - "type-is": "^1.6.16" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": ">=6" + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/apollo-server-express/node_modules/apollo-datasource": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.9.0.tgz", - "integrity": "sha512-y8H99NExU1Sk4TvcaUxTdzfq2SZo6uSj5dyh75XSQvbpH6gdAXIW9MaBcvlNC7n0cVPsidHmOcHOWxJ/pTXGjA==", + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dependencies": { - "apollo-server-caching": "^0.7.0", - "apollo-server-env": "^3.1.0" + "debug": "4" }, "engines": { - "node": ">=6" + "node": ">= 6.0.0" } }, - "node_modules/apollo-server-express/node_modules/apollo-server-core": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.25.3.tgz", - "integrity": "sha512-Midow3uZoJ9TjFNeCNSiWElTVZlvmB7G7tG6PPoxIR9Px90/v16Q6EzunDIO0rTJHRC3+yCwZkwtf8w2AcP0sA==", + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, "dependencies": { - "@apollographql/apollo-tools": "^0.5.0", - "@apollographql/graphql-playground-html": "1.6.27", - "@apollographql/graphql-upload-8-fork": "^8.1.3", - "@josephg/resolvable": "^1.0.0", - "@types/ws": "^7.0.0", - "apollo-cache-control": "^0.14.0", - "apollo-datasource": "^0.9.0", - "apollo-graphql": "^0.9.0", - "apollo-reporting-protobuf": "^0.8.0", - "apollo-server-caching": "^0.7.0", - "apollo-server-env": "^3.1.0", - "apollo-server-errors": "^2.5.0", - "apollo-server-plugin-base": "^0.13.0", - "apollo-server-types": "^0.9.0", - "apollo-tracing": "^0.15.0", - "async-retry": "^1.2.1", - "fast-json-stable-stringify": "^2.0.0", - "graphql-extensions": "^0.15.0", - "graphql-tag": "^2.11.0", - "graphql-tools": "^4.0.8", - "loglevel": "^1.6.7", - "lru-cache": "^6.0.0", - "sha.js": "^2.4.11", - "subscriptions-transport-ws": "^0.9.19", - "uuid": "^8.0.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/apollo-server-express/node_modules/apollo-server-errors": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.5.0.tgz", - "integrity": "sha512-lO5oTjgiC3vlVg2RKr3RiXIIQ5pGXBFxYGGUkKDhTud3jMIhs+gel8L8zsEjKaKxkjHhCQAA/bcEfYiKkGQIvA==", + "node_modules/amp": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", + "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==" + }, + "node_modules/amp-message": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", + "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==", + "dependencies": { + "amp": "0.3.1" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "engines": { "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/apollo-server-express/node_modules/apollo-server-plugin-base": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz", - "integrity": "sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { - "apollo-server-types": "^0.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/apollo-server-express/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/apollo-server-plugin-base": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.6.2.tgz", - "integrity": "sha512-erWXjLOO1u7fxQkbxJ2cwSO7p0tYzNied91I1SJ9tikXZ/2eZUyDyvrpI+4g70kOdEi+AmJ5Fo8ahEXKJ75zdg==", + "node_modules/apollo-cache-control": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.15.0.tgz", + "integrity": "sha512-U2uYvHZsWmR6s6CD5zlq3PepfbUAM8953CeVM2Y2QYMtJ8i4CYplEPbIWb3zTIXSPbIPeWGddM56pChI6Iz3zA==", "dependencies": { - "apollo-server-types": "^3.6.2" + "apollo-server-env": "^3.2.0", + "apollo-server-plugin-base": "^0.14.0" }, "engines": { - "node": ">=12.0" + "node": ">=6.0" }, "peerDependencies": { - "graphql": "^15.3.0 || ^16.0.0" + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/apollo-server-plugin-base/node_modules/@apollo/protobufjs": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.4.tgz", - "integrity": "sha512-npVJ9NVU/pynj+SCU+fambvTneJDyCnif738DnZ7pCxdDtzeEz7WkpSIq5wNUmWm5Td55N+S2xfqZ+WP4hDLng==", + "node_modules/apollo-cache-control/node_modules/@apollo/protobufjs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -3501,55 +4148,53 @@ "apollo-pbts": "bin/pbts" } }, - "node_modules/apollo-server-plugin-base/node_modules/@types/node": { + "node_modules/apollo-cache-control/node_modules/@types/node": { "version": "10.17.60", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" }, - "node_modules/apollo-server-plugin-base/node_modules/apollo-reporting-protobuf": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.2.tgz", - "integrity": "sha512-j1tx9tmkVdsLt1UPzBrvz90PdjAeKW157WxGn+aXlnnGfVjZLIRXX3x5t1NWtXvB7rVaAsLLILLtDHW382TSoQ==", + "node_modules/apollo-cache-control/node_modules/apollo-reporting-protobuf": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", "dependencies": { - "@apollo/protobufjs": "1.2.4" + "@apollo/protobufjs": "1.2.2" } }, - "node_modules/apollo-server-plugin-base/node_modules/apollo-server-env": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", - "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", + "node_modules/apollo-cache-control/node_modules/apollo-server-env": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", "dependencies": { - "node-fetch": "^2.6.7" + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" }, "engines": { - "node": ">=12.0" + "node": ">=6" } }, - "node_modules/apollo-server-plugin-base/node_modules/apollo-server-types": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.6.2.tgz", - "integrity": "sha512-9Z54S7NB+qW1VV+kmiqwU2Q6jxWfX89HlSGCGOo3zrkrperh85LrzABgN9S92+qyeHYd72noMDg2aI039sF3dg==", + "node_modules/apollo-cache-control/node_modules/apollo-server-plugin-base": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.14.0.tgz", + "integrity": "sha512-nTNSFuBhZURGjtWptdVqwemYUOdsvABj/GSKzeNvepiEubiv4N0rt4Gvy1inHDiMbo98wQTdF/7XohNcB9A77g==", "dependencies": { - "@apollo/utils.keyvaluecache": "^1.0.1", - "@apollo/utils.logger": "^1.0.0", - "apollo-reporting-protobuf": "^3.3.2", - "apollo-server-env": "^4.2.1" + "apollo-server-types": "^0.10.0" }, "engines": { - "node": ">=12.0" + "node": ">=6" }, "peerDependencies": { - "graphql": "^15.3.0 || ^16.0.0" + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/apollo-server-types": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.9.0.tgz", - "integrity": "sha512-qk9tg4Imwpk732JJHBkhW0jzfG0nFsLqK2DY6UhvJf7jLnRePYsPxWfPiNkxni27pLE2tiNlCwoDFSeWqpZyBg==", + "node_modules/apollo-cache-control/node_modules/apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", "dependencies": { "apollo-reporting-protobuf": "^0.8.0", "apollo-server-caching": "^0.7.0", - "apollo-server-env": "^3.1.0" + "apollo-server-env": "^3.2.0" }, "engines": { "node": ">=6" @@ -3558,913 +4203,927 @@ "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/apollo-tracing": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.15.0.tgz", - "integrity": "sha512-UP0fztFvaZPHDhIB/J+qGuy6hWO4If069MGC98qVs0I8FICIGu4/8ykpX3X3K6RtaQ56EDAWKykCxFv4ScxMeA==", - "deprecated": "The `apollo-tracing` package is no longer part of Apollo Server 3. See https://www.apollographql.com/docs/apollo-server/migration/#tracing for details", - "dependencies": { - "apollo-server-env": "^3.1.0", - "apollo-server-plugin-base": "^0.13.0" + "node_modules/apollo-datasource": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-3.3.2.tgz", + "integrity": "sha512-L5TiS8E2Hn/Yz7SSnWIVbZw0ZfEIXZCa5VUiVxD9P53JvSrf4aStvsFDlGWPvpIdCR+aly2CfoB79B9/JjKFqg==", + "dependencies": { + "@apollo/utils.keyvaluecache": "^1.0.1", + "apollo-server-env": "^4.2.1" }, "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "node": ">=12.0" } }, - "node_modules/apollo-tracing/node_modules/apollo-server-plugin-base": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz", - "integrity": "sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg==", + "node_modules/apollo-graphql": { + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.7.tgz", + "integrity": "sha512-bezL9ItUWUGHTm1bI/XzIgiiZbhXpsC7uxk4UxFPmcVJwJsDc3ayZ99oXxAaK+3Rbg/IoqrHckA6CwmkCsbaSA==", "dependencies": { - "apollo-server-types": "^0.9.0" + "core-js-pure": "^3.10.2", + "lodash.sortby": "^4.7.0", + "sha.js": "^2.4.11" }, "engines": { "node": ">=6" }, "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" - } - }, - "node_modules/apollo-upload-client": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-13.0.0.tgz", - "integrity": "sha512-lJ9/bk1BH1lD15WhWRha2J3+LrXrPIX5LP5EwiOUHv8PCORp4EUrcujrA3rI5hZeZygrTX8bshcuMdpqpSrvtA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.9.2", - "apollo-link": "^1.2.12", - "apollo-link-http-common": "^0.2.14", - "extract-files": "^8.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/jaydenseric" + "graphql": "^14.2.1 || ^15.0.0" } }, - "node_modules/apollo-utilities": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz", - "integrity": "sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==", + "node_modules/apollo-link": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz", + "integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==", "dependencies": { - "@wry/equality": "^0.1.2", - "fast-json-stable-stringify": "^2.0.0", + "apollo-utilities": "^1.3.0", "ts-invariant": "^0.4.0", - "tslib": "^1.10.0" + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.21" }, "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "graphql": "^0.11.3 || ^0.12.3 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/apollo-utilities/node_modules/tslib": { + "node_modules/apollo-link/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/apollo-reporting-protobuf": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.3.tgz", + "integrity": "sha512-L3+DdClhLMaRZWVmMbBcwl4Ic77CnEBPXLW53F7hkYhkaZD88ivbCVB1w/x5gunO6ZHrdzhjq0FHmTsBvPo7aQ==", "dependencies": { - "sprintf-js": "~1.0.2" + "@apollo/protobufjs": "1.2.6" } }, - "node_modules/argparse/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "node_modules/apollo-server-caching": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.7.0.tgz", + "integrity": "sha512-MsVCuf/2FxuTFVhGLK13B+TZH9tBd2qkyoXKKILIiGcZ5CDUEBO14vIV63aNkMkS1xxvK2U4wBcuuNj/VH2Mkw==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=6" + } }, - "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, + "node_modules/apollo-server-core": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.11.1.tgz", + "integrity": "sha512-t/eCKrRFK1lYZlc5pHD99iG7Np7CEm3SmbDiONA7fckR3EaB/pdsEdIkIwQ5QBBpT5JLp/nwvrZRVwhaWmaRvw==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" + "@apollo/utils.keyvaluecache": "^1.0.1", + "@apollo/utils.logger": "^1.0.0", + "@apollo/utils.usagereporting": "^1.0.0", + "@apollographql/apollo-tools": "^0.5.3", + "@apollographql/graphql-playground-html": "1.6.29", + "@graphql-tools/mock": "^8.1.2", + "@graphql-tools/schema": "^8.0.0", + "@josephg/resolvable": "^1.0.0", + "apollo-datasource": "^3.3.2", + "apollo-reporting-protobuf": "^3.3.3", + "apollo-server-env": "^4.2.1", + "apollo-server-errors": "^3.3.1", + "apollo-server-plugin-base": "^3.7.1", + "apollo-server-types": "^3.7.1", + "async-retry": "^1.2.1", + "fast-json-stable-stringify": "^2.1.0", + "graphql-tag": "^2.11.0", + "loglevel": "^1.6.8", + "lru-cache": "^6.0.0", + "node-abort-controller": "^3.0.1", + "sha.js": "^2.4.11", + "uuid": "^9.0.0", + "whatwg-mimetype": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=12.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/apollo-server-core/node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, + "node_modules/apollo-server-env": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", + "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "node-fetch": "^2.6.7" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12.0" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "node_modules/apollo-server-errors": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-3.3.1.tgz", + "integrity": "sha512-xnZJ5QWs6FixHICXHxUfm+ZWqqxrNuPlQ+kj5m6RtEgIpekOPssH/SD9gf2B4HuWV0QozorrygwZnux8POvyPA==", "engines": { - "node": ">=0.10.0" + "node": ">=12.0" + }, + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "node_modules/apollo-server-express": { + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.26.1.tgz", + "integrity": "sha512-eATTtlGhZFuo4KNRgaQ25jflUchI18oMd0vZyx0uIQ/CM0FPttO1noQ0fPAO6U0oSrxS8J9fCh8naJFDTUsZ0w==", "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "@apollographql/graphql-playground-html": "1.6.27", + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.19.0", + "@types/cors": "2.8.10", + "@types/express": "^4.17.12", + "@types/express-serve-static-core": "^4.17.21", + "accepts": "^1.3.5", + "apollo-server-core": "^2.26.1", + "apollo-server-types": "^0.10.0", + "body-parser": "^1.18.3", + "cors": "^2.8.5", + "express": "^4.17.1", + "graphql-subscriptions": "^1.0.0", + "graphql-tools": "^4.0.8", + "parseurl": "^1.3.2", + "subscriptions-transport-ws": "^0.9.19", + "type-is": "^1.6.16" + }, "engines": { - "node": ">=0.8" + "node": ">=6" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "node_modules/apollo-server-express/node_modules/@apollo/protobufjs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "hasInstallScript": true, "dependencies": { - "tslib": "^2.0.1" + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" }, - "engines": { - "node": ">=4" + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/apollo-server-express/node_modules/@apollographql/graphql-playground-html": { + "version": "1.6.27", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.27.tgz", + "integrity": "sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw==", + "dependencies": { + "xss": "^1.0.8" } }, - "node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + "node_modules/apollo-server-express/node_modules/@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } }, - "node_modules/async-hook-jl": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", - "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", + "node_modules/apollo-server-express/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "node_modules/apollo-server-express/node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "dependencies": { - "stack-chain": "^1.3.7" - }, - "engines": { - "node": "^4.7 || >=6.9 || >=7.3" + "@types/node": "*" } }, - "node_modules/async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "node_modules/apollo-server-express/node_modules/apollo-datasource": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.10.0.tgz", + "integrity": "sha512-wrLhuoM2MtA0KA0+3qyioe0H2FjAxjTvuFOlNCk6WberA887m0MQlWULZImCWTkKuN+zEAMerHfxN+F+W8+lBA==", "dependencies": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" }, "engines": { - "node": "<=0.11.8 || >0.11.10" + "node": ">=6" } }, - "node_modules/async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "node_modules/apollo-server-express/node_modules/apollo-reporting-protobuf": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", "dependencies": { - "retry": "0.13.1" + "@apollo/protobufjs": "1.2.2" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/babel-jest": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", - "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", - "dev": true, + "node_modules/apollo-server-express/node_modules/apollo-server-core": { + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.26.1.tgz", + "integrity": "sha512-YnO1YXhHOnCY7Q2SZ0uUtPq6SLCw+t2uI19l59mzWuCyZYdHrtSy3zUEU6pM3tR9vvUuRGkYIfMRlo/Q8a1U5g==", "dependencies": { - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.4.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" + "@apollographql/apollo-tools": "^0.5.0", + "@apollographql/graphql-playground-html": "1.6.27", + "@apollographql/graphql-upload-8-fork": "^8.1.4", + "@josephg/resolvable": "^1.0.0", + "@types/ws": "^7.0.0", + "apollo-cache-control": "^0.15.0", + "apollo-datasource": "^0.10.0", + "apollo-graphql": "^0.9.0", + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0", + "apollo-server-errors": "^2.5.0", + "apollo-server-plugin-base": "^0.14.0", + "apollo-server-types": "^0.10.0", + "apollo-tracing": "^0.16.0", + "async-retry": "^1.2.1", + "fast-json-stable-stringify": "^2.0.0", + "graphql-extensions": "^0.16.0", + "graphql-tag": "^2.11.0", + "graphql-tools": "^4.0.8", + "loglevel": "^1.6.7", + "lru-cache": "^6.0.0", + "sha.js": "^2.4.11", + "subscriptions-transport-ws": "^0.9.19", + "uuid": "^8.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" }, "peerDependencies": { - "@babel/core": "^7.8.0" + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, + "node_modules/apollo-server-express/node_modules/apollo-server-env": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, + "node_modules/apollo-server-express/node_modules/apollo-server-errors": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.5.0.tgz", + "integrity": "sha512-lO5oTjgiC3vlVg2RKr3RiXIIQ5pGXBFxYGGUkKDhTud3jMIhs+gel8L8zsEjKaKxkjHhCQAA/bcEfYiKkGQIvA==", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "node": ">=6" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", - "dev": true, + "node_modules/apollo-server-express/node_modules/apollo-server-plugin-base": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.14.0.tgz", + "integrity": "sha512-nTNSFuBhZURGjtWptdVqwemYUOdsvABj/GSKzeNvepiEubiv4N0rt4Gvy1inHDiMbo98wQTdF/7XohNcB9A77g==", "dependencies": { - "babel-plugin-jest-hoist": "^27.4.0", - "babel-preset-current-node-syntax": "^1.0.0" + "apollo-server-types": "^0.10.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "node_modules/apollo-server-express/node_modules/apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", "dependencies": { - "safe-buffer": "5.1.2" + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" }, "engines": { - "node": ">= 0.8" + "node": ">=6" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" + "node_modules/apollo-server-express/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" - }, - "node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", - "optional": true, + "node_modules/apollo-server-plugin-base": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.7.1.tgz", + "integrity": "sha512-g3vJStmQtQvjGI289UkLMfThmOEOddpVgHLHT2bNj0sCD/bbisj4xKbBHETqaURokteqSWyyd4RDTUe0wAUDNQ==", + "dependencies": { + "apollo-server-types": "^3.7.1" + }, "engines": { - "node": "*" + "node": ">=12.0" + }, + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/apollo-server-types": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.7.1.tgz", + "integrity": "sha512-aE9RDVplmkaOj/OduNmGa+0a1B5RIWI0o3zC1zLvBTVWMKTpo0ifVf11TyMkLCY+T7cnZqVqwyShziOyC3FyUw==", + "dependencies": { + "@apollo/utils.keyvaluecache": "^1.0.1", + "@apollo/utils.logger": "^1.0.0", + "apollo-reporting-protobuf": "^3.3.3", + "apollo-server-env": "^4.2.1" + }, "engines": { - "node": ">=8" + "node": ">=12.0" + }, + "peerDependencies": { + "graphql": "^15.3.0 || ^16.0.0" } }, - "node_modules/bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "node_modules/apollo-tracing": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.16.0.tgz", + "integrity": "sha512-Oy8kTggB+fJ/hHXwHyMpuTl5KW7u1XetKFDErZVOobUKc2zjc/NgWiC/s7SGYZCgfLodBjvwfa6rMcvLkz7c0w==", "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "apollo-server-env": "^3.2.0", + "apollo-server-plugin-base": "^0.14.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/bl/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "node_modules/apollo-tracing/node_modules/@apollo/protobufjs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "hasInstallScript": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" } }, - "node_modules/bl/node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "node_modules/apollo-tracing/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/apollo-tracing/node_modules/apollo-reporting-protobuf": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", "dependencies": { - "safe-buffer": "~5.1.0" + "@apollo/protobufjs": "1.2.2" } }, - "node_modules/bl/node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/blessed": { - "version": "0.1.81", - "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha1-+WLWh+wsNpVwrnGvhDJW5tDKESk=", - "bin": { - "blessed": "bin/tput.js" + "node_modules/apollo-tracing/node_modules/apollo-server-env": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", + "dependencies": { + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" - }, - "node_modules/bodec": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", - "integrity": "sha1-vIUVVUMPI8n3ZQp172TGqUw0GMw=" - }, - "node_modules/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "node_modules/apollo-tracing/node_modules/apollo-server-plugin-base": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.14.0.tgz", + "integrity": "sha512-nTNSFuBhZURGjtWptdVqwemYUOdsvABj/GSKzeNvepiEubiv4N0rt4Gvy1inHDiMbo98wQTdF/7XohNcB9A77g==", "dependencies": { - "bytes": "3.1.1", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" + "apollo-server-types": "^0.10.0" }, "engines": { - "node": ">= 0.8" + "node": ">=6" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "node_modules/apollo-tracing/node_modules/apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" }, "engines": { - "node": ">=8" + "node": ">=6" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/boxen/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/apollo-utilities": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz", + "integrity": "sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.10.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "engines": { - "node": ">=8" - } + "node_modules/apollo-utilities/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "dev": true, + "node_modules/array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", "dependencies": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "optional": true, "engines": { - "node": ">=0.6.19" + "node": ">=8" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "safer-buffer": "~2.1.0" } }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/busboy": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", - "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "node_modules/asn1js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", + "dev": true, "dependencies": { - "dicer": "0.3.0" + "pvtsutils": "^1.3.2", + "pvutils": "^1.1.3", + "tslib": "^2.4.0" }, "engines": { - "node": ">=4.5.0" + "node": ">=12.0.0" } }, - "node_modules/bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "engines": { - "node": ">= 0.8" + "node": ">=0.8" } }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dependencies": { - "pump": "^3.0.0" + "tslib": "^2.0.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { + "node_modules/astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/async-hook-jl": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz", + "integrity": "sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "stack-chain": "^1.3.7" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { - "node": ">=6" + "node": "^4.7 || >=6.9 || >=7.3" } }, - "node_modules/camel-case": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", - "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", - "dev": true, + "node_modules/async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", "dependencies": { - "pascal-case": "^3.1.1", - "tslib": "^1.10.0" + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "engines": { + "node": "<=0.11.8 || >0.11.10" } }, - "node_modules/camel-case/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "node_modules/async-listener/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dependencies": { + "retry": "0.13.1" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001305", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001305.tgz", - "integrity": "sha512-p7d9YQMji8haf0f+5rbcv9WlQ+N5jMPfRAnUmZRlNxsNeBO3Yr7RYG6M2uTY1h9tCVdlkJg6YNNc4kiAiBLdWA==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", "dev": true, + "engines": { + "node": ">=8" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", - "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - }, - "bin": { - "cdl": "bin/cdl.js" + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "engines": { + "node": "*" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, - "node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "follow-redirects": "^1.14.0" } }, - "node_modules/chance": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/chance/-/chance-1.1.8.tgz", - "integrity": "sha512-v7fi5Hj2VbR6dJEGRWLmJBA83LJMS47pkAbmROFxHWd9qmE1esHRZW8Clf1Fhzr3rjxnNZVCjOEv/ivFxeIMtg==", + "node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", "dev": true }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" + "node_modules/babel-preset-fbjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", + "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", + "dev": true, + "dependencies": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" }, - "node_modules/charm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", - "integrity": "sha1-BsIe7RobBq62dVPNxT4jJ0usIpY=" + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "devOptional": true, "funding": [ { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } - ], + ] + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "safe-buffer": "5.1.2" }, "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": ">= 0.8" } }, - "node_modules/ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", - "dev": true + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } }, - "node_modules/clean-stack": { + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, + "node_modules/bignumber.js": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/cli-boxes": { + "node_modules/bl": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "node_modules/bl/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "engines": { - "node": ">=6" + "node_modules/bl/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==", + "bin": { + "blessed": "bin/tput.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "node_modules/bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "node_modules/bodec": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", + "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==" + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { - "string-width": "^4.2.0" + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/cli-tableau": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", - "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "chalk": "3.0.0" + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-tableau/node_modules/chalk": { + "node_modules/boxen/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4473,3243 +5132,3416 @@ "node": ">=8" } }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "node_modules/boxen/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "devOptional": true, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, "engines": { - "node": ">=0.8" + "node": ">=8" } }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], "dependencies": { - "mimic-response": "^1.0.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/cls-bluebird": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", - "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, "dependencies": { - "is-bluebird": "^1.0.2", - "shimmer": "^1.1.0" + "node-int64": "^0.4.0" } }, - "node_modules/cls-hooked": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", - "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", - "dependencies": { - "async-hook-jl": "^1.7.6", - "emitter-listener": "^1.0.1", - "semver": "^5.4.1" - }, + "node_modules/bson": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", + "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", "engines": { - "node": "^4.7 || >=6.9 || >=7.3 || >=8.2.1" + "node": ">=0.6.19" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "streamsearch": "^1.1.0" + }, "engines": { - "node": ">=0.1.90" + "node": ">=10.16.0" } }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "optional": true, + "node_modules/c8": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz", + "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==", + "dev": true, "dependencies": { - "mime-db": ">= 1.43.0 < 2" + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-reports": "^3.1.4", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9" + }, + "bin": { + "c8": "bin/c8.js" }, "engines": { - "node": ">= 0.6" + "node": ">=10.12.0" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "node_modules/c8/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "devOptional": true, + "node_modules/c8/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dependencies": { - "safe-buffer": "5.2.1" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" }, - "engines": { - "node": ">= 0.6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=6" } }, - "node_modules/continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, "dependencies": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" } }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" + "engines": { + "node": ">=6" } }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "node_modules/caniuse-lite": { + "version": "1.0.30001429", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz", + "integrity": "sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, - "node_modules/copy-paste": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/copy-paste/-/copy-paste-1.3.0.tgz", - "integrity": "sha1-p+bEocKP3t8rCB5yuX3y75X0ce0=", + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, "dependencies": { - "iconv-lite": "^0.4.8" - }, - "optionalDependencies": { - "sync-exec": "~0.6.x" - } - }, - "node_modules/core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" } }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, "dependencies": { - "object-assign": "^4", - "vary": "^1" + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" }, - "engines": { - "node": ">= 0.10" + "bin": { + "cdl": "bin/cdl.js" } }, - "node_modules/cron": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", - "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", - "dependencies": { - "moment-timezone": "^0.5.x" - } + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" }, "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" + "node": ">=4" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "devOptional": true, - "engines": { - "node": ">=8" + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" } }, - "node_modules/cssfilter": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", - "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "node_modules/change-case-all": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.14.tgz", + "integrity": "sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA==", "dev": true, "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" + "change-case": "^4.1.2", + "is-lower-case": "^2.0.2", + "is-upper-case": "^2.0.2", + "lower-case": "^2.0.2", + "lower-case-first": "^2.0.2", + "sponge-case": "^1.0.1", + "swap-case": "^2.0.2", + "title-case": "^3.0.3", + "upper-case": "^2.0.2", + "upper-case-first": "^2.0.2" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "node_modules/culvert": { + "node_modules/charm": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", - "integrity": "sha1-lQL18BVKLVoioCPnn3HMk2+m728=" + "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", + "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==" }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "assert-plus": "^1.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=0.10" + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, "engines": { - "node": ">= 6" + "node": ">=6" } }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, "engines": { - "node": ">=10" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/data-urls/node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "dependencies": { - "punycode": "^2.1.1" + "restore-cursor": "^3.1.0" }, "engines": { "node": ">=8" } }, - "node_modules/data-urls/node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "node_modules/cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", "dev": true, "engines": { - "node": ">=10.4" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" + "string-width": "^4.2.0" }, "engines": { - "node": ">=10" + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "node_modules/dayjs": { - "version": "1.8.36", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", - "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/cli-tableau": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", + "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", "dependencies": { - "ms": "2.0.0" + "chalk": "3.0.0" + }, + "engines": { + "node": ">=8.10.0" } }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, + "node_modules/cli-tableau/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dependencies": { - "mimic-response": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, "engines": { - "node": ">=4.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 10" } }, - "node_modules/defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "dependencies": { - "clone": "^1.0.2" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/cls-bluebird": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", + "integrity": "sha512-XVb0RPmHQyy35Tz9z34gvtUcBKUK8A/1xkGCyeFc9B0C7Zr5SysgFaswRVdwI5NEMcO+3JKlIDGIOgERSn9NdA==", "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" + "is-bluebird": "^1.0.2", + "shimmer": "^1.1.0" } }, - "node_modules/degenerator": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.1.tgz", - "integrity": "sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==", + "node_modules/cls-hooked": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/cls-hooked/-/cls-hooked-4.2.2.tgz", + "integrity": "sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==", "dependencies": { - "ast-types": "^0.13.2", - "escodegen": "^1.8.1", - "esprima": "^4.0.0", - "vm2": "^3.9.3" + "async-hook-jl": "^1.7.6", + "emitter-listener": "^1.0.1", + "semver": "^5.4.1" }, "engines": { - "node": ">= 6" + "node": "^4.7 || >=6.9 || >=7.3 || >=8.2.1" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" + "node_modules/cls-hooked/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" } }, - "node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", - "engines": { - "node": ">=0.10" + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">= 0.6" + "node": ">=7.0.0" } }, - "node_modules/deprecated-decorator": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", - "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=" + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" } }, - "node_modules/dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", "dependencies": { - "streamsearch": "0.1.2" + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=4.5.0" + "node": ">= 0.8" } }, - "node_modules/diff-sequences": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", - "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", + "node_modules/commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4.0.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, "dependencies": { - "path-type": "^4.0.0" + "mime-db": ">= 1.43.0 < 2" }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concurrently": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.5.0.tgz", + "integrity": "sha512-5E3mwiS+i2JYBzr5BpXkFxOnleZTMsG+WnE/dCG4/P+oiVXrbmrBwJ2ozn4SxwB2EZDrKR568X+puVohxz3/Mg==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "chalk": "^4.1.0", + "date-fns": "^2.29.1", + "lodash": "^4.17.21", + "rxjs": "^7.0.0", + "shell-quote": "^1.7.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^17.3.1" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" }, "engines": { - "node": ">=6.0.0" + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "webidl-conversions": "^5.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "optional": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "devOptional": true, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, "dependencies": { - "is-obj": "^2.0.0" + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "engines": { - "node": ">=10" + "node": ">= 0.6" } }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "node_modules/continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "dependencies": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, - "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "optional": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" } }, - "node_modules/easygraphql-mock": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/easygraphql-mock/-/easygraphql-mock-0.1.17.tgz", - "integrity": "sha512-J+OLxUfV0dw5LjMlargd9iAjtur7ifgrC0djZQgDnxXLj0g5K0JQX48cY9S95Tw4MXZP24y79w5MJtJxPcDwgQ==", - "dev": true, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/copy-paste": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/copy-paste/-/copy-paste-1.3.0.tgz", + "integrity": "sha512-HA6le4vPZW2EuPFixuGUpVRKPdAmZyRlF30x5lTbfX7xXHN9NwX/+Sff7Getowosoe/lZIFwrjn4hvsYGe2vRw==", "dependencies": { - "chance": "^1.0.16", - "easygraphql-parser": "^0.0.15" + "iconv-lite": "^0.4.8" + }, + "optionalDependencies": { + "sync-exec": "~0.6.x" } }, - "node_modules/easygraphql-mock/node_modules/easygraphql-parser": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/easygraphql-parser/-/easygraphql-parser-0.0.15.tgz", - "integrity": "sha512-0fEXFnFlIjgyo1rxBmEsOa1wYZwIEm5Qk3qLR1bY4d7iMsPNIPKy4M6eohyQHYXww0v3RYWrHNoks0QnktJ9bw==", + "node_modules/copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", "dev": true, "dependencies": { - "@graphql-tools/merge": "^6.0.11" + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0 || ^15.0.0" + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" } }, - "node_modules/easygraphql-parser": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/easygraphql-parser/-/easygraphql-parser-0.0.12.tgz", - "integrity": "sha512-lawcyfGQHY0DkDlHYCMhUOoe/O6q2gdzVLcHIXerkoAcz3ScMjLdxInO76JRuEpWc/TerPZ+HaHs18+4c79V1w==", + "node_modules/copyfiles/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { - "graphql": "^14.4.0", - "merge-graphql-schemas": "^1.5.8" - }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/easygraphql-parser/node_modules/graphql": { - "version": "14.7.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", - "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", + "node_modules/copyfiles/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "iterall": "^1.2.2" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">= 6.x" + "node": ">=10" } }, - "node_modules/easygraphql-tester": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/easygraphql-tester/-/easygraphql-tester-5.1.6.tgz", - "integrity": "sha512-f2u8z9sgjfyZ2QGaie05oWUAYSyW2u1dq0IZImGXnD/Z20bKrJjbdI7q1Q+S51gIwP6EJGHwCTDGkPI6ClN2jQ==", - "dev": true, + "node_modules/core-js-pure": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.0.tgz", + "integrity": "sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dependencies": { - "easygraphql-mock": "^0.1.15", - "easygraphql-parser": "^0.0.12", - "graphql": "^14.4.0", - "graphql-tools": "^4.0.4", - "lodash.isempty": "^4.4.0", - "lodash.isobject": "^3.0.2", - "merge-graphql-schemas": "^1.5.8" + "object-assign": "^4", + "vary": "^1" }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0" + "engines": { + "node": ">= 0.10" } }, - "node_modules/easygraphql-tester/node_modules/graphql": { - "version": "14.7.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", - "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", "dev": true, "dependencies": { - "iterall": "^1.2.2" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "engines": { - "node": ">= 6.x" + "node": ">=10" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "node_modules/cosmiconfig-toml-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-toml-loader/-/cosmiconfig-toml-loader-1.0.0.tgz", + "integrity": "sha512-H/2gurFWVi7xXvCyvsWRLCMekl4tITJcX0QEsDMpzxtuxDyM59xLatYNg4s/k9AA/HdtCYfj2su8mgA0GSDLDA==", + "dev": true, "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "@iarna/toml": "^2.2.5" } }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" + "node_modules/cosmiconfig-typescript-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.1.1.tgz", + "integrity": "sha512-9DHpa379Gp0o0Zefii35fcmuuin6q92FnLDffzdZ0l9tVd3nEobG3O+MZ06+kuBvFTSVScvNb/oHA13Nd4iipg==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=7", + "ts-node": ">=10", + "typescript": ">=3" } }, - "node_modules/ee-first": { + "node_modules/create-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.61", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.61.tgz", - "integrity": "sha512-kpzCOOFlx63C9qKRyIDEsKIUgzoe98ump7T4gU+/OLzj8gYkkWf2SIyBjhTSE0keAjMAp3i7C262YtkQOMYrGw==", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "node_modules/emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "node_modules/croner": { + "version": "4.1.97", + "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", + "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==" + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dependencies": { - "shimmer": "^1.2.0" + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" } }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "dependencies": { + "node-fetch": "2.6.7" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/enabled": { + "node_modules/crypto-random-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "optional": true, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "devOptional": true, - "dependencies": { - "once": "^1.4.0" - } + "node_modules/cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "node_modules/culvert": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", + "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dependencies": { - "ansi-colors": "^4.1.1" + "assert-plus": "^1.0.0" }, "engines": { - "node": ">=8.6" + "node": ">=0.10" } }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "optional": true - }, - "node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + "node_modules/data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "engines": { + "node": ">= 6" + } }, - "node_modules/errors": { - "resolved": "lib/helper_lib/errors", - "link": true + "node_modules/dataloader": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.1.0.tgz", + "integrity": "sha512-qTcEYLen3r7ojZNgVUaRggOI+KM7jrKxXeSHhogh/TWxYMeONEMqY+hmkobiYQozsGIyg9OYVzO4ZIfoB4I0pQ==", + "dev": true }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, + "node_modules/date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=0.11" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/date-fns" } }, - "node_modules/es-to-primitive": { + "node_modules/dayjs": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" + }, + "node_modules/debounce": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "ms": "2.1.2" }, "engines": { - "node": ">= 0.4" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "devOptional": true, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, "engines": { - "node": ">=8" + "node": ">=0.12" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=4.0" + "node": ">= 0.4" }, - "optionalDependencies": { - "source-map": "~0.6.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, + "node_modules/degenerator": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.2.tgz", + "integrity": "sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ==", "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0", + "vm2": "^3.9.8" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 6" } }, - "node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" + "node": ">=0.4.0" } }, - "node_modules/eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" + "node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "engines": { + "node": ">=0.10" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">= 0.6.0" } }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "node_modules/deprecated-decorator": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", + "integrity": "sha512-MHidOOnCHGlZDKsI21+mbIIhf4Fff+hhCTB7gtVg4uoIqjcrTZc5v6M+GS2zVI0sV7PqK415rb8XaOSQsQkHOw==" }, - "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { - "node": ">=4" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">=8" } }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", - "dev": true, + "node_modules/dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", - "has": "^1.0.3", - "is-core-module": "^2.8.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" + "streamsearch": "0.1.2" }, "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "node": ">=4.5.0" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/dicer/node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.3.1" } }, - "node_modules/eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "^4.0.1" + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": ">= 4", - "eslint": ">=5" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - } + "node": ">=8" } }, - "node_modules/eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "esutils": "^2.0.2" }, "engines": { "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" + "no-case": "^3.0.4", + "tslib": "^2.0.3" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "optional": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "is-obj": "^2.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=8" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, + "node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/dset": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", + "integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==", "dev": true, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "optional": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/eslint/node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" + "safe-buffer": "^5.0.1" } }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", "dev": true }, - "node_modules/eslint/node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, + "node_modules/emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" + "shimmer": "^1.2.0" } }, - "node_modules/eslint/node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8" } }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "optional": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "once": "^1.4.0" } }, - "node_modules/eslint/node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dependencies": { - "prelude-ls": "^1.2.1" + "ansi-colors": "^4.1.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8.6" } }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "optional": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/esbuild": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", + "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, + "hasInstallScript": true, "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=4" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.15.13", + "@esbuild/linux-loong64": "0.15.13", + "esbuild-android-64": "0.15.13", + "esbuild-android-arm64": "0.15.13", + "esbuild-darwin-64": "0.15.13", + "esbuild-darwin-arm64": "0.15.13", + "esbuild-freebsd-64": "0.15.13", + "esbuild-freebsd-arm64": "0.15.13", + "esbuild-linux-32": "0.15.13", + "esbuild-linux-64": "0.15.13", + "esbuild-linux-arm": "0.15.13", + "esbuild-linux-arm64": "0.15.13", + "esbuild-linux-mips64le": "0.15.13", + "esbuild-linux-ppc64le": "0.15.13", + "esbuild-linux-riscv64": "0.15.13", + "esbuild-linux-s390x": "0.15.13", + "esbuild-netbsd-64": "0.15.13", + "esbuild-openbsd-64": "0.15.13", + "esbuild-sunos-64": "0.15.13", + "esbuild-windows-32": "0.15.13", + "esbuild-windows-64": "0.15.13", + "esbuild-windows-arm64": "0.15.13" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz", + "integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/esbuild-android-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz", + "integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=0.10" + "node": ">=12" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/esbuild-darwin-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz", + "integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=4.0" + "node": ">=12" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz", + "integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=4.0" + "node": ">=12" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/esbuild-freebsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz", + "integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=4.0" + "node": ">=12" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz", + "integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=4.0" + "node": ">=12" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/esbuild-linux-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz", + "integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "node_modules/esbuild-linux-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz", + "integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.6" + "node": ">=12" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "node_modules/esbuild-linux-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz", + "integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==", + "cpu": [ + "arm" + ], + "dev": true, "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/eventemitter2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", - "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=" - }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/esbuild-linux-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz", + "integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=12" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz", + "integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==", + "cpu": [ + "mips64el" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.8.0" + "node": ">=12" } }, - "node_modules/expect": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", - "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz", + "integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=12" } }, - "node_modules/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.6", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz", + "integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.10.0" + "node": ">=12" } }, - "node_modules/express-mongo-sanitize": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/express-mongo-sanitize/-/express-mongo-sanitize-2.2.0.tgz", - "integrity": "sha512-PZBs5nwhD6ek9ZuP+W2xmpvcrHwXZxD5GdieX2dsjPbAbH4azOkrHbycBud2QRU+YQF1CT+pki/lZGedHgo/dQ==", + "node_modules/esbuild-linux-s390x": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz", + "integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/express-rate-limit": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz", - "integrity": "sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz", + "integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/extract-files": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-8.1.0.tgz", - "integrity": "sha512-PTGtfthZK79WUMk+avLmwx3NGdU8+iVFXC2NMGxKsn0MnihOG2lvumj+AZo8CTwTrwjXDgZ5tztbRlEdRjBonQ==", + "node_modules/esbuild-openbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz", + "integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "10 - 12 || >= 13.7" - }, - "funding": { - "url": "https://github.com/sponsors/jaydenseric" + "node": ">=12" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "node_modules/esbuild-sunos-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz", + "integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=8.6.0" + "node": ">=12" } }, - "node_modules/fast-json-patch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.0.tgz", - "integrity": "sha512-IhpytlsVTRndz0hU5t0/MGzS/etxLlfrpG5V5M9mVbuj9TrJLWaMfsox9REM5rkuGX0T+5qjpe8XA1o0gZ42nA==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "node_modules/fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", - "optional": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "node_modules/esbuild-windows-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz", + "integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, + "node_modules/esbuild-windows-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz", + "integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=0.8.0" + "node": ">=12" } }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "node_modules/esbuild-windows-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz", + "integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "bser": "2.1.1" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "node_modules/fclone": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", - "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=" + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "devOptional": true, + "engines": { + "node": ">=6" + } }, - "node_modules/fecha": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", - "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, "engines": { - "node": ">=0.8.0" + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dependencies": { - "flat-cache": "^3.0.4" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.8.0" } }, - "node_modules/file-type": { - "version": "14.7.1", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-14.7.1.tgz", - "integrity": "sha512-sXAMgFk67fQLcetXustxfKX+PZgHIUFn96Xld9uH8aXPdX3xOp0/jg9OdouVTvQrf7mrn+wAa4jN/y9fUOOiRA==", + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dependencies": { - "readable-web-to-node-stream": "^2.0.0", - "strtok3": "^6.0.3", - "token-types": "^2.0.0", - "typedarray-to-buffer": "^3.1.5" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" + "node": ">= 0.8.0" } }, - "node_modules/file-uri-to-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", - "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "engines": { - "node": ">= 6" + "node": ">= 0.8.0" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dependencies": { - "to-regex-range": "^5.0.1" + "prelude-ls": "~1.1.2" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "node_modules/eslint": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", + "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "dev": true, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">= 0.8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "node_modules/eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", "dev": true, - "dependencies": { - "locate-path": "^2.0.0" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/firebase-admin": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-10.3.0.tgz", - "integrity": "sha512-A0wgMLEjyVyUE+heyMJYqHRkPVjpebhOYsa47RHdrTM4ltApcx8Tn86sUmjqxlfh09gNnILAm7a8q5+FmgBYpg==", + "node_modules/eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, "dependencies": { - "@fastify/busboy": "^1.1.0", - "@firebase/database-compat": "^0.2.0", - "@firebase/database-types": "^0.9.7", - "@types/node": ">=12.12.47", - "jsonwebtoken": "^8.5.1", - "jwks-rsa": "^2.0.2", - "node-forge": "^1.3.1", - "uuid": "^8.3.2" + "prettier-linter-helpers": "^1.0.0" }, "engines": { - "node": ">=12.7.0" + "node": ">=12.0.0" }, - "optionalDependencies": { - "@google-cloud/firestore": "^4.15.1", - "@google-cloud/storage": "^5.18.3" - } - }, - "node_modules/firebase-admin/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=8.0.0" } }, - "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, "engines": { - "node": ">=4.0" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, "engines": { - "node": "*" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.12" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=4.0" } }, - "node_modules/fs-capacitor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", - "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, "engines": { - "node": ">=8.5" + "node": ">=10.13.0" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/eslint/node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "node_modules/espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "dev": true, "dependencies": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=0.8.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/ftp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "node_modules/ftp/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/ftp/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "devOptional": true - }, - "node_modules/gaxios": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz", - "integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==", - "optional": true, - "dependencies": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.7" + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "optional": true, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, "dependencies": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=10" + "node": ">=0.10" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "devOptional": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=4.0" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "estraverse": "^5.2.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=4.0" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4.0" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4.0" } }, - "node_modules/get-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", - "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", - "dependencies": { - "@tootallnate/once": "1", - "data-uri-to-buffer": "3", - "debug": "4", - "file-uri-to-path": "2", - "fs-extra": "^8.1.0", - "ftp": "^0.3.10" - }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/get-uri/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 0.6" } }, - "node_modules/get-uri/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/event-target-polyfill": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/event-target-polyfill/-/event-target-polyfill-0.0.3.tgz", + "integrity": "sha512-ZMc6UuvmbinrCk4RzGyVmRyIsAyxMRlp4CqSrcQRO8Dy0A9ldbiRy5kdtBj4OtP7EClGdqGfIqo9JmOClMsGLQ==", + "dev": true }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "devOptional": true, + "engines": { + "node": ">=6" } }, - "node_modules/git-node-fs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", - "integrity": "sha1-SbIV4kLr5Dqkx1Ybu6SZUhdSCA8=" + "node_modules/eventemitter2": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", + "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==" }, - "node_modules/git-sha1": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", - "integrity": "sha1-WZrBkrcYdYJeE6RF86bgURjC90U=" + "node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 0.10.0" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, + "node_modules/express-mongo-sanitize": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/express-mongo-sanitize/-/express-mongo-sanitize-2.2.0.tgz", + "integrity": "sha512-PZBs5nwhD6ek9ZuP+W2xmpvcrHwXZxD5GdieX2dsjPbAbH4azOkrHbycBud2QRU+YQF1CT+pki/lZGedHgo/dQ==", "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, + "node_modules/express-rate-limit": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz", + "integrity": "sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "ms": "2.0.0" } }, - "node_modules/global-dirs/node_modules/ini": { + "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "engines": { - "node": ">=10" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4" } }, - "node_modules/globby": { + "node_modules/extract-files": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", - "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", + "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==", "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": "^12.20 || >= 14.13" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jaydenseric" } }, - "node_modules/google-auth-library": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz", - "integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==", - "optional": true, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=10" + "node": ">=8.6.0" } }, - "node_modules/google-auth-library/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true, - "engines": { - "node": ">=8" - } + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" }, - "node_modules/google-auth-library/node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "node_modules/google-auth-library/node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fast-text-encoding": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", + "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", + "optional": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" + "reusify": "^1.0.4" } }, - "node_modules/google-gax": { - "version": "2.30.5", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.30.5.tgz", - "integrity": "sha512-Jey13YrAN2hfpozHzbtrwEfEHdStJh1GwaQ2+Akh1k0Tv/EuNVSuBtHZoKSBm5wBMvNsxTsEIZ/152NrYyZgxQ==", - "optional": true, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dependencies": { - "@grpc/grpc-js": "~1.6.0", - "@grpc/proto-loader": "^0.6.12", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^7.14.0", - "is-stream-ended": "^0.1.4", - "node-fetch": "^2.6.1", - "object-hash": "^3.0.0", - "proto3-json-serializer": "^0.1.8", - "protobufjs": "6.11.3", - "retry-request": "^4.0.0" - }, - "bin": { - "compileProtos": "build/tools/compileProtos.js" + "websocket-driver": ">=0.5.1" }, "engines": { - "node": ">=10" + "node": ">=0.8.0" } }, - "node_modules/google-p12-pem": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz", - "integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==", - "optional": true, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, "dependencies": { - "node-forge": "^1.3.1" - }, - "bin": { - "gp12-pem": "build/src/bin/gp12-pem.js" - }, - "engines": { - "node": ">=10" + "bser": "2.1.1" } }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "node_modules/fbjs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.4.tgz", + "integrity": "sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==", "dev": true, "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" + "cross-fetch": "^3.1.5", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.30" } }, - "node_modules/got/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", + "dev": true + }, + "node_modules/fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==" + }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "dependencies": { - "pump": "^3.0.0" + "escape-string-regexp": "^1.0.5" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - }, - "node_modules/graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { - "node": ">= 10.x" + "node": ">=0.8.0" } }, - "node_modules/graphql-depth-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz", - "integrity": "sha512-+3B2BaG8qQ8E18kzk9yiSdAa75i/hnnOwgSeAxVJctGQPvmeiLtqKOYF6HETCyRjiF7Xfsyal0HbLlxCQkgkrw==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, "dependencies": { - "arrify": "^1.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "graphql": "*" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/graphql-extensions": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.15.0.tgz", - "integrity": "sha512-bVddVO8YFJPwuACn+3pgmrEg6I8iBuYLuwvxiE+lcQQ7POotVZxm2rgGw0PvVYmWWf3DT7nTVDZ5ROh/ALp8mA==", - "deprecated": "The `graphql-extensions` API has been removed from Apollo Server 3. Use the plugin API instead: https://www.apollographql.com/docs/apollo-server/integrations/plugins/", + "node_modules/file-type": { + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-14.7.1.tgz", + "integrity": "sha512-sXAMgFk67fQLcetXustxfKX+PZgHIUFn96Xld9uH8aXPdX3xOp0/jg9OdouVTvQrf7mrn+wAa4jN/y9fUOOiRA==", "dependencies": { - "@apollographql/apollo-tools": "^0.5.0", - "apollo-server-env": "^3.1.0", - "apollo-server-types": "^0.9.0" + "readable-web-to-node-stream": "^2.0.0", + "strtok3": "^6.0.3", + "token-types": "^2.0.0", + "typedarray-to-buffer": "^3.1.5" }, "engines": { - "node": ">=6.0" + "node": ">=8" }, - "peerDependencies": { - "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/graphql-subscriptions": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz", - "integrity": "sha512-95yD/tKi24q8xYa7Q9rhQN16AYj5wPbrb8tmHGM3WRc9EBmWrG/0kkMl+tQG8wcEuE9ibR4zyOM31p5Sdr2v4g==", - "dependencies": { - "iterall": "^1.3.0" - }, - "peerDependencies": { - "graphql": "^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "node_modules/file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", + "engines": { + "node": ">= 6" } }, - "node_modules/graphql-tag": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { - "tslib": "^2.1.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + "node": ">=8" } }, - "node_modules/graphql-tools": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", - "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", - "deprecated": "This package has been deprecated and now it only exports makeExecutableSchema.\\nAnd it will no longer receive updates.\\nWe recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc.\\nCheck out https://www.graphql-tools.com to learn what package you should use instead", + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { - "apollo-link": "^1.2.14", - "apollo-utilities": "^1.0.1", - "deprecated-decorator": "^0.1.6", - "iterall": "^1.1.3", - "uuid": "^3.1.0" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0 || ^15.0.0" + "engines": { + "node": ">= 0.8" } }, - "node_modules/graphql-upload": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/graphql-upload/-/graphql-upload-12.0.0.tgz", - "integrity": "sha512-ovZ3Q7sZ17Bmn8tYl22MfrpNR7nYM/DUszXWgkue7SFIlI9jtqszHAli8id8ZcnGBc9GF0gUTNSskYWW+5aNNQ==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "busboy": "^0.3.1", - "fs-capacitor": "^6.2.0", - "http-errors": "^1.8.0", - "isobject": "^4.0.0", - "object-path": "^0.11.5" + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^12.20 || >= 14.13" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/jaydenseric" - }, - "peerDependencies": { - "graphql": "0.13.1 - 15" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graphql-upload/node_modules/fs-capacitor": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-6.2.0.tgz", - "integrity": "sha512-nKcE1UduoSKX27NSZlg879LdQc94OtbOsEmKMN2MBNudXREvijRKx2GEBsTMTfws+BrbkJoEuynbGSVRSpauvw==", + "node_modules/firebase-admin": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-10.3.0.tgz", + "integrity": "sha512-A0wgMLEjyVyUE+heyMJYqHRkPVjpebhOYsa47RHdrTM4ltApcx8Tn86sUmjqxlfh09gNnILAm7a8q5+FmgBYpg==", + "dependencies": { + "@fastify/busboy": "^1.1.0", + "@firebase/database-compat": "^0.2.0", + "@firebase/database-types": "^0.9.7", + "@types/node": ">=12.12.47", + "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^2.0.2", + "node-forge": "^1.3.1", + "uuid": "^8.3.2" + }, "engines": { - "node": ">=10" + "node": ">=12.7.0" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^4.15.1", + "@google-cloud/storage": "^5.18.3" } }, - "node_modules/graphql-ws": { - "version": "5.6.4", - "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.6.4.tgz", - "integrity": "sha512-5r8tAzznI1zeh7k12+3z07KkgXPckQbnC9h4kJ2TBDWG2wb26TJTbVHQOiAncDBgPbtXtc1A2BlttiRuPH2t/w==", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "graphql": ">=0.11 <=16" + "node_modules/firebase-admin/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/gtoken": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz", - "integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==", - "optional": true, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, "dependencies": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.1.3", - "jws": "^4.0.0" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=10" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/gtoken/node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/gtoken/node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" + "is-callable": "^1.1.3" } }, - "node_modules/har-schema": { + "node_modules/foreground-child": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "engines": { - "node": ">=6" + "node": "*" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, "dependencies": { - "function-bind": "^1.1.1" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.4.0" + "node": ">= 6" } }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "dev": true }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dev": true, + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, "engines": { - "node": ">=8" + "node": ">= 12.20" } }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 14" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/hash-stream-validation": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", - "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", - "optional": true - }, - "node_modules/helmet": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz", - "integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==", + "node_modules/fs-capacitor": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-6.2.0.tgz", + "integrity": "sha512-nKcE1UduoSKX27NSZlg879LdQc94OtbOsEmKMN2MBNudXREvijRKx2GEBsTMTfws+BrbkJoEuynbGSVRSpauvw==", "engines": { - "node": ">=10.0.0" + "node": ">=10" } }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dependencies": { - "whatwg-encoding": "^1.0.5" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=10" + "node": ">=6 <7 || >=8" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "node_modules/ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" + "readable-stream": "1.1.x", + "xregexp": "2.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=0.8.0" } }, - "node_modules/http-parser-js": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz", - "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==" + "node_modules/ftp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "node_modules/ftp/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/ftp/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dependencies": { - "ms": "2.1.2" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/http-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "optional": true }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz", + "integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==", + "optional": true, "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.7" }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">=10" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "node_modules/gcp-metadata": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", + "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", + "optional": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6.9.0" } }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true, "engines": { - "node": ">=10.17.0" + "node": "*" } }, - "node_modules/i18n": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.13.4.tgz", - "integrity": "sha512-GZnXWeA15jTi9gc1jfgrJcSrNYDg7qbJXSYMuibqPYb1ThORmGCeM+gL6LrDagYRHh87/q/D0jRSOhAfv6wAow==", + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dependencies": { - "debug": "^4.3.3", - "make-plural": "^7.0.0", - "math-interval-parser": "^2.0.1", - "messageformat": "^2.3.0", - "mustache": "^4.2.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=0.10.0" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" }, "funding": { - "url": "https://github.com/sponsors/mashpie" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/i18n/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dependencies": { - "ms": "2.1.2" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/i18n/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/get-tsconfig": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.2.0.tgz", + "integrity": "sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/get-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, + "node_modules/get-uri/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "engines": { - "node": ">= 4" + "node": ">= 6" } }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "node_modules/image-hash": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/image-hash/-/image-hash-4.0.1.tgz", - "integrity": "sha512-RoNf9UH91p+SlAWT7vgIzfXn5EgAR+LgPGSkk5PRK6QW2PPLWzANh3GwCh9wICFsz7+vfaa12ug6k3tfPwgoSg==", + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dependencies": { - "file-type": "^14.6.2", - "jpeg-js": "^0.4.0", - "pngjs": "^3.3.3", - "request": "^2.81.0" + "assert-plus": "^1.0.0" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "node_modules/git-node-fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", + "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==" + }, + "node_modules/git-sha1": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", + "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=6" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, "engines": { "node": ">=4" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "node_modules/google-auth-library": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz", + "integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==", + "optional": true, "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=10" } }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/google-gax": { + "version": "2.30.5", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.30.5.tgz", + "integrity": "sha512-Jey13YrAN2hfpozHzbtrwEfEHdStJh1GwaQ2+Akh1k0Tv/EuNVSuBtHZoKSBm5wBMvNsxTsEIZ/152NrYyZgxQ==", + "optional": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@grpc/grpc-js": "~1.6.0", + "@grpc/proto-loader": "^0.6.12", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^7.14.0", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^0.1.8", + "protobufjs": "6.11.3", + "retry-request": "^4.0.0" + }, + "bin": { + "compileProtos": "build/tools/compileProtos.js" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "node_modules/google-p12-pem": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz", + "integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==", + "optional": true, "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "node-forge": "^1.3.1" + }, + "bin": { + "gp12-pem": "build/src/bin/gp12-pem.js" }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", "engines": { - "node": ">= 0.10" + "node": ">= 10.x" } }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/graphql-config": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-4.3.6.tgz", + "integrity": "sha512-i7mAPwc0LAZPnYu2bI8B6yXU5820Wy/ArvmOseDLZIu0OU1UTULEuexHo6ZcHXeT9NvGGaUPQZm8NV3z79YydA==", + "dev": true, "dependencies": { - "has-bigints": "^1.0.1" + "@graphql-tools/graphql-file-loader": "^7.3.7", + "@graphql-tools/json-file-loader": "^7.3.7", + "@graphql-tools/load": "^7.5.5", + "@graphql-tools/merge": "^8.2.6", + "@graphql-tools/url-loader": "^7.9.7", + "@graphql-tools/utils": "^8.6.5", + "cosmiconfig": "7.0.1", + "cosmiconfig-toml-loader": "1.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", + "minimatch": "4.2.1", + "string-env-interpolation": "1.0.1", + "ts-node": "^10.8.1", + "tslib": "^2.4.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/graphql-config/node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" - } - }, - "node_modules/is-bluebird": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", - "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=", - "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/graphql-depth-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz", + "integrity": "sha512-+3B2BaG8qQ8E18kzk9yiSdAa75i/hnnOwgSeAxVJctGQPvmeiLtqKOYF6HETCyRjiF7Xfsyal0HbLlxCQkgkrw==", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "arrify": "^1.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "graphql": "*" } }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "node_modules/graphql-depth-limit/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, + "node_modules/graphql-extensions": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.16.0.tgz", + "integrity": "sha512-rZQc/USoEIw437BGRUwoHoLPR1LA791Ltj6axONqgKIyyx2sqIO3YT9kTbB/eIUdJBrCozp4KuUeZ09xKeQDxg==", "dependencies": { - "ci-info": "^2.0.0" + "@apollographql/apollo-tools": "^0.5.0", + "apollo-server-env": "^3.2.0", + "apollo-server-types": "^0.10.0" }, - "bin": { - "is-ci": "bin.js" + "engines": { + "node": ">=6.0" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/is-ci/node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "node_modules/graphql-extensions/node_modules/@apollo/protobufjs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "hasInstallScript": true, "dependencies": { - "has": "^1.0.3" + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/graphql-extensions/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "node_modules/graphql-extensions/node_modules/apollo-reporting-protobuf": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", "dependencies": { - "has-tostringtag": "^1.0.0" + "@apollo/protobufjs": "1.2.2" + } + }, + "node_modules/graphql-extensions/node_modules/apollo-server-env": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", + "dependencies": { + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "node_modules/graphql-extensions/node_modules/apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", + "dependencies": { + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "peerDependencies": { + "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" + "node_modules/graphql-request": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-5.0.0.tgz", + "integrity": "sha512-SpVEnIo2J5k2+Zf76cUkdvIRaq5FMZvGQYnA4lUWYbc99m+fHh4CZYRRO/Ff4tCLQ613fzCm3SiDT64ubW5Gyw==", + "dev": true, + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "cross-fetch": "^3.1.5", + "extract-files": "^9.0.0", + "form-data": "^3.0.0" + }, + "peerDependencies": { + "graphql": "14 - 16" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "node_modules/graphql-request/node_modules/extract-files": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", + "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", "dev": true, "engines": { - "node": ">=6" + "node": "^10.17.0 || ^12.0.0 || >= 13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/jaydenseric" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/graphql-subscriptions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz", + "integrity": "sha512-95yD/tKi24q8xYa7Q9rhQN16AYj5wPbrb8tmHGM3WRc9EBmWrG/0kkMl+tQG8wcEuE9ibR4zyOM31p5Sdr2v4g==", "dependencies": { - "is-extglob": "^2.1.1" + "iterall": "^1.3.0" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "graphql": "^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" + "tslib": "^2.1.0" }, "engines": { "node": ">=10" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "engines": { - "node": ">=8" + "node_modules/graphql-tools": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", + "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", + "deprecated": "This package has been deprecated and now it only exports makeExecutableSchema.\\nAnd it will no longer receive updates.\\nWe recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc.\\nCheck out https://www.graphql-tools.com to learn what package you should use instead", + "dependencies": { + "apollo-link": "^1.2.14", + "apollo-utilities": "^1.0.1", + "deprecated-decorator": "^0.1.6", + "iterall": "^1.1.3", + "uuid": "^3.1.0" + }, + "peerDependencies": { + "graphql": "^0.13.0 || ^14.0.0 || ^15.0.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "node_modules/graphql-upload": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/graphql-upload/-/graphql-upload-12.0.0.tgz", + "integrity": "sha512-ovZ3Q7sZ17Bmn8tYl22MfrpNR7nYM/DUszXWgkue7SFIlI9jtqszHAli8id8ZcnGBc9GF0gUTNSskYWW+5aNNQ==", + "dependencies": { + "busboy": "^0.3.1", + "fs-capacitor": "^6.2.0", + "http-errors": "^1.8.0", + "isobject": "^4.0.0", + "object-path": "^0.11.5" + }, "engines": { - "node": ">= 0.4" + "node": "^12.20 || >= 14.13" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jaydenseric" + }, + "peerDependencies": { + "graphql": "0.13.1 - 15" } }, - "node_modules/is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true, - "engines": { - "node": ">=10" + "node_modules/graphql-upload/node_modules/busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "dependencies": { + "dicer": "0.3.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4.5.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/graphql-upload/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "engines": { - "node": ">=0.12.0" + "node": ">= 0.6" } }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "node_modules/graphql-upload/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dependencies": { - "has-tostringtag": "^1.0.0" + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "devOptional": true, + "node_modules/graphql-upload/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/graphql-ws": { + "version": "5.11.2", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.11.2.tgz", + "integrity": "sha512-4EiZ3/UXYcjm+xFGP544/yW1+DVI8ZpKASFbzrV5EDTFWJp0ZvLl4Dy2fSZAzz9imKp5pZMIcjB0x/H69Pv/6w==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "peerDependencies": { + "graphql": ">=0.11 <=16" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "node_modules/gtoken": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz", + "integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==", + "optional": true, + "dependencies": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.1.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "ajv": "^6.12.3", + "har-schema": "^2.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.4.0" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "optional": true - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dependencies": { - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.1.1" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -7717,10 +8549,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dependencies": { "has-symbols": "^1.0.2" }, @@ -7731,817 +8563,734 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "node_modules/hash-stream-validation": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", + "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", + "optional": true }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/helmet": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz", + "integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==", + "engines": { + "node": ">=10.0.0" } }, - "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { + "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "devOptional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, + "node_modules/i18n": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.13.4.tgz", + "integrity": "sha512-GZnXWeA15jTi9gc1jfgrJcSrNYDg7qbJXSYMuibqPYb1ThORmGCeM+gL6LrDagYRHh87/q/D0jRSOhAfv6wAow==", "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "debug": "^4.3.3", + "make-plural": "^7.0.0", + "math-interval-parser": "^2.0.1", + "messageformat": "^2.3.0", + "mustache": "^4.2.0", + "sprintf-js": "^1.1.2" }, "engines": { - "node": ">=10" + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mashpie" } }, - "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { - "ms": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/istanbul-lib-source-maps/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/istanbul-reports": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", - "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">= 4" } }, - "node_modules/iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" + "node_modules/image-hash": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/image-hash/-/image-hash-4.0.1.tgz", + "integrity": "sha512-RoNf9UH91p+SlAWT7vgIzfXn5EgAR+LgPGSkk5PRK6QW2PPLWzANh3GwCh9wICFsz7+vfaa12ug6k3tfPwgoSg==", + "dependencies": { + "file-type": "^14.6.2", + "jpeg-js": "^0.4.0", + "pngjs": "^3.3.3", + "request": "^2.81.0" + } }, - "node_modules/jest": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", - "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", + "node_modules/immutable": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", + "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", "dev": true, - "dependencies": { - "@jest/core": "^27.4.7", - "import-local": "^3.0.2", - "jest-cli": "^27.4.7" - }, - "bin": { - "jest": "bin/jest.js" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": ">=0.8.0" } }, - "node_modules/jest-changed-files": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", - "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", - "execa": "^5.0.0", - "throat": "^6.0.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-circus": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", - "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.4.6", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-config": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", - "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.4.6", - "@jest/types": "^27.4.2", - "babel-jest": "^27.4.6", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.6", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", - "slash": "^3.0.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "node": ">=4" } }, - "node_modules/jest-diff": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", - "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", + "node_modules/import-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.4.0", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" + "engines": { + "node": ">=12.2" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "devOptional": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.8.19" } }, - "node_modules/jest-docblock": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", - "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/jest-each": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", - "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", - "dev": true, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/jest-environment-jsdom": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", - "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", "dev": true, "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2", - "jsdom": "^16.6.0" + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=12.0.0" } }, - "node_modules/jest-environment-node": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", - "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", - "dev": true, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4" } }, - "node_modules/jest-get-type": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", - "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.10" } }, - "node_modules/jest-haste-map": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", - "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "micromatch": "^4.0.4", - "walker": "^1.0.7" + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "node": ">=0.10.0" } }, - "node_modules/jest-jasmine2": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", - "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", - "dev": true, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.4.6", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", - "throat": "^6.0.1" + "has-bigints": "^1.0.1" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-leak-detector": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", - "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", - "dev": true, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" + "binary-extensions": "^2.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/jest-matcher-utils": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", - "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - }, + "node_modules/is-bluebird": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", + "integrity": "sha512-PDRu1vVip5dGQg5tfn2qVCCyxbBYu5MhYUJwSfL/RoGBI97n1fxvilVazxzptZW0gcmsMH17H4EVZZI5E/RSeA==", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-message-util": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", - "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", - "dev": true, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.4.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.16.7" - }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-mock": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", - "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", - "dev": true, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dependencies": { - "@jest/types": "^27.4.2", - "@types/node": "*" + "has": "^1.0.3" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "engines": { - "node": ">=6" + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" }, - "peerDependencies": { - "jest-resolve": "*" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", - "dev": true, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-resolve": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", - "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/jest-resolve-dependencies": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", - "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", - "dev": true, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { - "@jest/types": "^27.4.2", - "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.6" + "is-extglob": "^2.1.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-runner": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", - "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", - "dev": true, - "dependencies": { - "@jest/console": "^27.4.6", - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-haste-map": "^27.4.6", - "jest-leak-detector": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", - "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/globals": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "node_modules/is-lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", + "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", "dev": true, "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "tslib": "^2.0.3" } }, - "node_modules/jest-snapshot": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", - "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", - "natural-compare": "^1.4.0", - "pretty-format": "^27.4.6", - "semver": "^7.3.2" - }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { - "node": ">=10" + "node": ">=0.12.0" } }, - "node_modules/jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", - "dev": true, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dependencies": { - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", - "picomatch": "^2.2.3" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-validate": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", - "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.4.2", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", - "leven": "^3.1.0", - "pretty-format": "^27.4.6" - }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "optional": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-watcher": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", - "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "dependencies": { - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.4.2", - "string-length": "^4.0.1" + "is-unc-path": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-worker": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", - "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", - "dev": true, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "call-bind": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "engines": { - "node": ">= 10.13.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", + "optional": true + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "unc-path-regex": "^0.1.2" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest/node_modules/jest-cli": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", - "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", + "node_modules/is-upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", + "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", "dev": true, "dependencies": { - "@jest/core": "^27.4.7", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.4.7", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" + "tslib": "^2.0.3" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "dev": true, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "ws": "*" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, + "node_modules/iterall": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" + }, "node_modules/jose": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", - "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz", + "integrity": "sha512-FVoPY7SflDodE4lknJmbAHSUjLCzE2H1F6MS0RYKMQ8SR+lNccpMf8R4eqkNYyyUjR5qZReOzZo5C5YiHOCjjg==", "dependencies": { "@panva/asn1.js": "^1.0.0" }, @@ -8553,14 +9302,14 @@ } }, "node_modules/jpeg-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", - "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" }, "node_modules/js-git": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", - "integrity": "sha1-UvplWrYYd9bxB578ZTS1VPMeVEQ=", + "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==", "dependencies": { "bodec": "^0.1.0", "culvert": "^0.1.2", @@ -8568,6 +9317,12 @@ "pako": "^0.2.5" } }, + "node_modules/js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8575,13 +9330,12 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -8590,186 +9344,34 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, "bin": { - "acorn": "bin/acorn" + "jsesc": "bin/jsesc" }, "engines": { - "node": ">=0.4.0" + "node": ">=4" } }, - "node_modules/jsdom/node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "optional": true, "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "bignumber.js": "^9.0.0" } }, - "node_modules/jsdom/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/jsdom/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsdom/node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsdom/node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jsdom/node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/jsdom/node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "optional": true, - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "node_modules/json-schema": { "version": "0.4.0", @@ -8781,37 +9383,68 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha512-i/J297TW6xyj7sDFa7AmBPkQvLIxWr2kKPWI26tXydnZrzVAocNqn5DMNT1Mzk0vit1V5UkRM7C1KdVNp7Lmcg==", + "dev": true, + "dependencies": { + "jsonify": "~0.0.0" + } + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "node_modules/json-to-pretty-yaml": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz", + "integrity": "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==", "dev": true, "dependencies": { - "minimist": "^1.2.0" + "remedial": "^1.0.7", + "remove-trailing-spaces": "^1.0.6" }, + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, "bin": { "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -8833,10 +9466,32 @@ "npm": ">=1.4.28" } }, - "node_modules/jsonwebtoken/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } }, "node_modules/jsprim": { "version": "1.4.2", @@ -8853,9 +9508,10 @@ } }, "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -8863,14 +9519,14 @@ } }, "node_modules/jwks-rsa": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.4.tgz", - "integrity": "sha512-mpArfgPkUpX11lNtGxsF/szkasUcbWHGplZl/uFvFO2NuMHmt0dQXIihh0rkPU2yQd5niQtuUHbXnG/WKiXF6Q==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.5.tgz", + "integrity": "sha512-IODtn1SwEm7n6GQZnQLY0oxKDrMh7n/jRH1MzE8mlxWMrh2NnMyOsXTebu8vJ1qCpmuTJcL4DdiE0E4h8jnwsA==", "dependencies": { - "@types/express": "^4.17.13", - "@types/jsonwebtoken": "^8.5.8", + "@types/express": "^4.17.14", + "@types/jsonwebtoken": "^8.5.9", "debug": "^4.3.4", - "jose": "^2.0.5", + "jose": "^2.0.6", "limiter": "^1.1.5", "lru-memoizer": "^2.1.4" }, @@ -8878,33 +9534,13 @@ "node": ">=10 < 13 || >=14" } }, - "node_modules/jwks-rsa/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/jwks-rsa/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, "dependencies": { - "jwa": "^1.4.1", + "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, @@ -8918,65 +9554,27 @@ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" }, - "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "dependencies": { - "package-json": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/lazy": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", - "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=", + "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==", "engines": { "node": ">=0.2.0" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -8987,25 +9585,64 @@ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "node_modules/linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/listr2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "dev": true, "dependencies": { - "uc.micro": "^1.0.1" + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.5", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/local-pkg": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", + "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -9027,44 +9664,38 @@ "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" }, "node_modules/lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "node_modules/lodash.isempty": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", - "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", - "dev": true + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "node_modules/lodash.isobject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", - "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", - "dev": true + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" }, "node_modules/lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.lowercase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz", + "integrity": "sha512-UcvP1IZYyDKyEL64mmrwoA1AbFu5ahojhTtkOUr1K9dbuxzS9ev8i4TxMMGCqRC9TE8uDaSoufNAXxRPNTseVA==", + "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -9075,18 +9706,12 @@ "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, "node_modules/log-driver": { "version": "1.2.7", @@ -9100,6 +9725,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -9111,42 +9737,77 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/logform": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.2.tgz", - "integrity": "sha512-V6JiPThZzTsbVRspNO6TmHkR99oqYTs8fivMBYQkjZj6rxW92KxtDCPE6IkAk1DNBnYKNkjm4jYBm6JDUcyhOA==", + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, "dependencies": { - "colors": "1.4.0", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^1.1.0", - "triple-beam": "^1.3.0" - } - }, - "node_modules/logform/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/logform/node_modules/safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" - }, - "node_modules/logger": { - "resolved": "lib/helper_lib/logger", - "link": true - }, - "node_modules/loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, "engines": { - "node": ">= 0.6.0" + "node": ">=10" }, "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/loglevel" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logform": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", + "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", + "dependencies": { + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, + "node_modules/loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" } }, "node_modules/long": { @@ -9154,6 +9815,27 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -9163,13 +9845,13 @@ "tslib": "^2.0.3" } }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "node_modules/lower-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", + "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "tslib": "^2.0.3" } }, "node_modules/lru-cache": { @@ -9221,117 +9903,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" - } + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/make-plural": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.0.0.tgz", - "integrity": "sha512-OTuzMnuhrc7G3LJU5upkhKy7EIAq/dRqANqTUh0B8au7jM5mXq9kVdla3sn3g2GCRIxgooCDQtSJ3s1fAjasbQ==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.1.0.tgz", + "integrity": "sha512-PKkwVlAxYVo98NrbclaQIT4F5Oy+X58PZM5r2IwUSCe3syya6PXkIRCn2XCdz7p58Scgpp50PBeHmepXVDG3hg==" }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/markdown-it": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.1.tgz", - "integrity": "sha512-CzzqSSNkFRUf9vlWvhK1awpJreMRqdCrBvZ8DIoDWTOkESMIF741UPAhuAmbyWmdiFPA6WARNhnu2M6Nrhwa+A==", - "dependencies": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-js": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/markdown-js/-/markdown-js-0.0.4.tgz", - "integrity": "sha512-/GDVAINnE6JXDE18JXjRXFmkE66k9rWIUOUvZPFsOlSQNQEcJEI/tiKsOMSBbTOerQV3V0/jiuVjZ3vxYO8nnQ==", - "dependencies": { - "markdown-it": "8.4.1", - "test": ">=0.0.5" + "engines": { + "node": ">=0.10.0" } }, "node_modules/marked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.1.tgz", - "integrity": "sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true, "bin": { "marked": "bin/marked" }, "engines": { - "node": ">= 8.16.2" + "node": ">= 10" } }, "node_modules/marked-terminal": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.1.1.tgz", - "integrity": "sha512-+cKTOx9P4l7HwINYhzbrBSyzgxO2HaHKGZGuB1orZsMIgXYaJyfidT81VXRdpelW/PcHEWxywscePVgI/oUF6g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-4.2.0.tgz", + "integrity": "sha512-DQfNRV9svZf0Dm9Cf5x5xaVJ1+XjxQW6XjFJ5HFkVyK52SDpj5PCBzS5X5r2w9nHr3mlB0T5201UMLue9fmhUw==", + "dev": true, "dependencies": { - "ansi-escapes": "^5.0.0", + "ansi-escapes": "^4.3.1", "cardinal": "^2.1.1", - "chalk": "^5.0.0", - "cli-table3": "^0.6.1", - "node-emoji": "^1.11.0", - "supports-hyperlinks": "^2.2.0" - }, - "engines": { - "node": ">=14.13.1 || >=16.0.0" + "chalk": "^4.1.0", + "cli-table3": "^0.6.0", + "node-emoji": "^1.10.0", + "supports-hyperlinks": "^2.1.0" }, "peerDependencies": { - "marked": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" - } - }, - "node_modules/marked-terminal/node_modules/ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/marked-terminal/node_modules/chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/marked-terminal/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "marked": "^1.0.0 || ^2.0.0" } }, "node_modules/math-interval-parser": { @@ -9342,15 +9960,10 @@ "node": ">=0.10.0" } }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } @@ -9364,34 +9977,7 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/merge-graphql-schemas": { - "version": "1.7.8", - "resolved": "https://registry.npmjs.org/merge-graphql-schemas/-/merge-graphql-schemas-1.7.8.tgz", - "integrity": "sha512-C3EJ1i86OjmbcCT524wVPRl17M5VZzgyh9kIGYAlYnAILX+7xfh8cCbMKfehh9n4opZg6CtcPogCiVZ6PB2NyQ==", - "deprecated": "Merge GraphQL Schemas has been deprecated and merged into GraphQL Tools, so it will no longer get updates. Use GraphQL Tools instead to stay up-to-date! Check out https://www.graphql-tools.com/docs/migration-from-merge-graphql-schemas for migration and https://the-guild.dev/blog/graphql-tools-v6 for new changes.", - "dev": true, - "dependencies": { - "@graphql-toolkit/file-loading": "0.10.4", - "@graphql-toolkit/schema-merging": "0.10.4", - "tslib": "1.11.1" - }, - "peerDependencies": { - "graphql": "^0.11.7 || ^0.13.0 || ^14.0.2 || ^15.0.0" - } - }, - "node_modules/merge-graphql-schemas/node_modules/tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/merge2": { "version": "1.4.1", @@ -9402,11 +9988,28 @@ "node": ">= 8" } }, + "node_modules/meros": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/meros/-/meros-1.2.1.tgz", + "integrity": "sha512-R2f/jxYqCAGI19KhAvaxSOxALBMkaXWH2a7rOyqQw+ZmizX5bKkEYWLzdhC+U82ZVVPVp6MCXe3EkVligh+12g==", + "dev": true, + "engines": { + "node": ">=13" + }, + "peerDependencies": { + "@types/node": ">=13" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/messageformat": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "deprecated": "Package renamed as '@messageformat/core', see messageformat.github.io for more details. 'messageformat' will eventually provide a polyfill for Intl.MessageFormat, once it's been defined by Unicode & ECMA.", + "deprecated": "Package renamed as '@messageformat/core', see messageformat.github.io for more details. 'messageformat@4' will eventually provide a polyfill for Intl.MessageFormat, once it's been defined by Unicode & ECMA.", "dependencies": { "make-plural": "^4.3.0", "messageformat-formatters": "^2.0.1", @@ -9437,49 +10040,50 @@ "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "optional": true, "bin": { "mime": "cli.js" }, "engines": { - "node": ">=4" + "node": ">=10.0.0" } }, "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -9489,23 +10093,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -9514,10 +10110,13 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "devOptional": true + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/mkdirp": { "version": "1.0.4", @@ -9533,26 +10132,7 @@ "node_modules/module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" - }, - "node_modules/moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.34", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", - "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", - "dependencies": { - "moment": ">= 2.9.0" - }, - "engines": { - "node": "*" - } + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, "node_modules/mongodb": { "version": "3.7.3", @@ -9604,9 +10184,9 @@ } }, "node_modules/mongoose": { - "version": "5.13.14", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.14.tgz", - "integrity": "sha512-j+BlQjjxgZg0iWn42kLeZTB91OejcxWpY2Z50bsZTiKJ7HHcEtcY21Godw496GMkBqJMTzmW7G/kZ04mW+Cb7Q==", + "version": "5.13.15", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.15.tgz", + "integrity": "sha512-cxp1Gbb8yUWkaEbajdhspSaKzAvsIvOtRlYD87GN/P2QEUhpd6bIvebi36T6M0tIVAMauNaK9SPA055N3PwF8Q==", "dependencies": { "@types/bson": "1.x || 4.0.x", "@types/mongodb": "^3.5.27", @@ -9640,18 +10220,13 @@ } }, "node_modules/mongoose-paginate-v2": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mongoose-paginate-v2/-/mongoose-paginate-v2-1.5.0.tgz", - "integrity": "sha512-+r/M/gYfR98s1ooXoSH3aD3bMopjXKR6UpzQZSDWI22uNtoIpxia4/b80X99ho3g8AMzl0uLuQFuPL06mXHyyg==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mongoose-paginate-v2/-/mongoose-paginate-v2-1.7.1.tgz", + "integrity": "sha512-J8DJw3zRXcXOKoZv+RvO9tt5HotRnbo2iCR3lke+TtsQsYwQvbY3EgUkPqZXw6qCX2IByvXrW5SGNdAB0od/Cw==", "engines": { "node": ">=4.0.0" } }, - "node_modules/mongoose/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -9667,10 +10242,26 @@ "node": ">= 0.8.0" } }, - "node_modules/morgan/node_modules/depd": { + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, "engines": { "node": ">= 0.8" } @@ -9706,15 +10297,20 @@ "ms": "2.0.0" } }, + "node_modules/mquery/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/mquery/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mustache": { "version": "4.2.0", @@ -9730,14 +10326,26 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "node_modules/nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, "node_modules/needle": { @@ -9764,15 +10372,10 @@ "ms": "^2.1.1" } }, - "node_modules/needle/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { "node": ">= 0.6" } @@ -9795,18 +10398,44 @@ "tslib": "^2.0.3" } }, + "node_modules/node-abort-controller": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", + "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==" + }, "node_modules/node-cmd": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/node-cmd/-/node-cmd-5.0.0.tgz", "integrity": "sha512-4sQTJmsS5uZKAPz/Df9fnIbmvOySfGdW+UreH4X5NcAOOpKjaE+K5wf4ehNBbZVPo0vQ36RkRnhhsXXJAT+Syw==", + "dev": true, "engines": { "node": ">=6.4.0" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, "dependencies": { "lodash": "^4.17.21" } @@ -9841,102 +10470,56 @@ "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, "node_modules/node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "node_modules/nodemailer": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.5.tgz", - "integrity": "sha512-6VtMpwhsrixq1HDYSBBHvW0GwiWawE75dS3oal48VqRhUvKJNnKnJo2RI/bCVQubj1vgrgscMNW4DHaD6xtMCg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", + "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==", "engines": { "node": ">=6.0.0" } }, - "node_modules/nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "node_modules/noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", "dev": true, - "hasInstallScript": true, "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5", - "update-notifier": "^5.1.0" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" } }, - "node_modules/nodemon/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/noms/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/noms/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } + "node_modules/noms/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -9946,31 +10529,10 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/nssocket": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", - "integrity": "sha1-Wflvb/MhVm8zxw99vu7N/cBxVPo=", + "integrity": "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==", "dependencies": { "eventemitter2": "~0.4.14", "lazy": "~1.0.11" @@ -9982,12 +10544,12 @@ "node_modules/nssocket/node_modules/eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=" + "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==" }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", "dev": true }, "node_modules/oauth-sign": { @@ -10001,7 +10563,7 @@ "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } @@ -10016,9 +10578,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10040,13 +10602,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -10056,28 +10618,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", "dependencies": { + "array.prototype.reduce": "^1.0.4", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" }, "engines": { "node": ">= 0.8" @@ -10086,27 +10635,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, @@ -10125,7 +10657,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } @@ -10142,6 +10674,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -10161,16 +10694,17 @@ } }, "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { "node": ">= 0.8.0" @@ -10180,6 +10714,7 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -10202,6 +10737,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -10211,51 +10747,64 @@ "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "aggregate-error": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/pac-proxy-agent": { @@ -10277,68 +10826,54 @@ "node": ">= 8" } }, - "node_modules/pac-proxy-agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, + "node_modules/pac-proxy-agent/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 6" } }, - "node_modules/pac-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/pac-resolver": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.0.tgz", - "integrity": "sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==", + "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dependencies": { - "degenerator": "^3.0.1", - "ip": "^1.1.5", - "netmask": "^2.0.1" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">= 8" + "node": ">= 6" } }, - "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, + "node_modules/pac-resolver": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", + "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" + "degenerator": "^3.0.2", + "ip": "^1.1.5", + "netmask": "^2.0.2" }, "engines": { - "node": ">=8" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">= 8" } }, "node_modules/pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=" + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } }, "node_modules/parent-module": { "version": "1.0.1", @@ -10352,11 +10887,37 @@ "node": ">=6" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/parseurl": { "version": "1.3.3", @@ -10376,19 +10937,29 @@ "tslib": "^2.0.3" } }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } @@ -10406,10 +10977,31 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/path-type": { "version": "4.0.0", @@ -10420,11 +11012,20 @@ "node": ">=8" } }, - "node_modules/peek-readable": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.0.2.tgz", - "integrity": "sha512-9fMaz6zoxw9ypO1KZy5RDJgSupEtu0Q+g/OqqsVHX3rKGR8qehRLYzsFARZ4bVvdvfknKiXvuDbkMnO1g6cRpQ==", - "engines": { + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "engines": { "node": ">=8" }, "funding": { @@ -10435,7 +11036,7 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "node_modules/picocolors": { "version": "1.0.0", @@ -10455,111 +11056,20 @@ } }, "node_modules/pidusage": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", - "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz", + "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==", "dependencies": { "safe-buffer": "^5.2.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/pm2": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.1.2.tgz", - "integrity": "sha512-2nJQeCWjkN0WnTkWctaoZpqrJTiUN/Icw76IMVHHzPhr/p7yQYlEQgHzlL5IFWxO2N1HdBNXNdZft2p4HUmUcA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.2.2.tgz", + "integrity": "sha512-mASxgh/MZhtVze/wijGf+tE6JKdA3lEq64FOfXVhhArkuk9Qxl4ePw9XgFJaArOXnU3bde+KbeAJHYxppVvYBQ==", "dependencies": { "@pm2/agent": "~2.0.0", "@pm2/io": "~5.0.0", @@ -10568,25 +11078,25 @@ "async": "~3.2.0", "blessed": "0.1.81", "chalk": "3.0.0", - "chokidar": "^3.5.1", + "chokidar": "^3.5.3", "cli-tableau": "^2.0.0", "commander": "2.15.1", - "cron": "1.8.2", - "dayjs": "~1.8.25", + "croner": "~4.1.92", + "dayjs": "~1.11.5", "debug": "^4.3.1", "enquirer": "2.3.6", "eventemitter2": "5.0.1", "fclone": "1.0.11", "mkdirp": "1.0.4", "needle": "2.4.0", - "pidusage": "2.0.21", + "pidusage": "~3.0", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.1", "pm2-deploy": "~1.0.2", "pm2-multimeter": "^0.1.2", "promptly": "^2", "semver": "^7.2", - "source-map-support": "0.5.19", + "source-map-support": "0.5.21", "sprintf-js": "1.1.2", "vizion": "~2.2.1", "yamljs": "0.3.0" @@ -10629,48 +11139,6 @@ "node": ">=5" } }, - "node_modules/pm2-axon-rpc/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/pm2-axon-rpc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/pm2-axon/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/pm2-axon/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/pm2-deploy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", @@ -10686,7 +11154,7 @@ "node_modules/pm2-multimeter": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", - "integrity": "sha1-Gh5VFT1BoFU0zqI8/oYKuqDrSs4=", + "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==", "dependencies": { "charm": "~0.1.1" } @@ -10704,35 +11172,16 @@ "tx2": "~1.0.4" } }, - "node_modules/pm2-sysmonit/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/pm2-sysmonit/node_modules/pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", "optional": true, "dependencies": { - "ms": "2.1.2" + "safe-buffer": "^5.2.1" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/pm2-sysmonit/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, - "node_modules/pm2/node_modules/@pm2/pm2-version-check": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", - "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", - "dependencies": { - "debug": "^4.3.1" + "node": ">=8" } }, "node_modules/pm2/node_modules/chalk": { @@ -10747,36 +11196,10 @@ "node": ">=8" } }, - "node_modules/pm2/node_modules/commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" - }, - "node_modules/pm2/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/pm2/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/pm2/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -10795,33 +11218,52 @@ "node": ">=4.0.0" } }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "node_modules/postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, "engines": { - "node": ">= 0.8.0" + "node": "^10 || ^12 || >=14" } }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-linter-helpers": { @@ -10836,67 +11278,28 @@ "node": ">=6.0.0" } }, - "node_modules/pretty-format": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", - "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "asap": "~2.0.3" } }, "node_modules/promptly": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", - "integrity": "sha1-KhP6BjaIoqWYOxYf/wEIoH0m/HQ=", + "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==", "dependencies": { "read": "^1.0.4" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/proto3-json-serializer": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.9.tgz", @@ -10962,20 +11365,25 @@ "node": ">= 8" } }, - "node_modules/proxy-agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/proxy-agent/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dependencies": { - "ms": "2.1.2" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 6" } }, "node_modules/proxy-agent/node_modules/lru-cache": { @@ -10986,11 +11394,6 @@ "yallist": "^3.0.2" } }, - "node_modules/proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/proxy-agent/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -11007,21 +11410,15 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "devOptional": true, + "optional": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -11046,22 +11443,31 @@ "node": ">=6" } }, - "node_modules/pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "node_modules/pvtsutils": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.2.tgz", + "integrity": "sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==", "dev": true, "dependencies": { - "escape-goat": "^2.0.0" - }, + "tslib": "^2.4.0" + } + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=6.0.0" } }, "node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" }, @@ -11098,12 +11504,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { - "bytes": "3.1.1", - "http-errors": "1.8.1", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -11111,40 +11517,10 @@ "node": ">= 0.8" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", "dependencies": { "mute-stream": "~0.0.4" }, @@ -11184,15 +11560,16 @@ "node_modules/redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, "dependencies": { "esprima": "~4.0.0" } }, "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", "dev": true }, "node_modules/regexp-clone": { @@ -11200,6 +11577,22 @@ "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -11212,34 +11605,36 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "node_modules/relay-runtime": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", + "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==", "dev": true, "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=6.0.0" + "@babel/runtime": "^7.0.0", + "fbjs": "^3.0.0", + "invariant": "^2.2.4" } }, - "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "node_modules/remedial": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", + "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, "engines": { - "node": ">=8" + "node": "*" } }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/remove-trailing-spaces": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz", + "integrity": "sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==", "dev": true }, "node_modules/request": { @@ -11273,9 +11668,18 @@ "node": ">= 6" } }, - "node_modules/request-tracing": { - "resolved": "lib/helper_lib/request-tracing", - "link": true + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } }, "node_modules/request/node_modules/qs": { "version": "6.5.3", @@ -11296,58 +11700,37 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "devOptional": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/require-in-the-middle": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", - "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz", + "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==", "dependencies": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - } - }, - "node_modules/require-in-the-middle/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" + "resolve": "^1.22.1" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6" } }, - "node_modules/require-in-the-middle/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -11358,19 +11741,7 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", @@ -11379,37 +11750,11 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -11439,29 +11784,6 @@ "node": ">=8.10.0" } }, - "node_modules/retry-request/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/retry-request/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -11472,6 +11794,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -11487,10 +11815,26 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, "engines": { "node": ">=0.12.0" } @@ -11538,9 +11882,10 @@ ] }, "node_modules/rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "dev": true, "dependencies": { "tslib": "^2.1.0" } @@ -11564,10 +11909,23 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-stable-stringify": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", - "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz", + "integrity": "sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==", "engines": { "node": ">=10" } @@ -11594,89 +11952,109 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } + "node_modules/scuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", + "integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==", + "dev": true }, "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -11713,6 +12091,15 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/shimmer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", @@ -11726,6 +12113,11 @@ "nanoid": "^2.1.0" } }, + "node_modules/shortid/node_modules/nanoid": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", + "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -11745,23 +12137,28 @@ "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" }, "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/signedsource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", + "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==", + "dev": true }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "dependencies": { "is-arrayish": "^0.3.1" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, "node_modules/slash": { "version": "3.0.0", @@ -11773,9 +12170,9 @@ } }, "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", @@ -11783,16 +12180,13 @@ "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" }, "node_modules/smart-buffer": { "version": "4.2.0", @@ -11803,13 +12197,23 @@ "npm": ">= 3.0.0" } }, - "node_modules/socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, "dependencies": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" }, "engines": { "node": ">= 10.13.0", @@ -11829,26 +12233,10 @@ "node": ">= 6" } }, - "node_modules/socks-proxy-agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socks-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/socks/node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" }, "node_modules/source-map": { "version": "0.6.1", @@ -11858,10 +12246,19 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -11870,12 +12267,27 @@ "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "dependencies": { "memory-pager": "^1.0.2" } }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "dev": true + }, + "node_modules/sponge-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", + "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", @@ -11908,43 +12320,22 @@ "node_modules/stack-chain": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", "engines": { "node": "*" } }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/stream-events": { @@ -11963,11 +12354,12 @@ "optional": true }, "node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=10.0.0" } }, "node_modules/string_decoder": { @@ -11978,23 +12370,17 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } + "node_modules/string-env-interpolation": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz", + "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==", + "dev": true }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -12005,24 +12391,26 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12032,6 +12420,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -12039,24 +12428,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -12069,13 +12440,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz", + "integrity": "sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/strtok3": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.2.4.tgz", - "integrity": "sha512-GO8IcFF9GmFDvqduIspUBwCzCbqzegyVKIsSymcMgiZKeCfrN9SowtUoi8+b59WZMAjIzVZic/Ft97+pynR3Iw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", "dependencies": { "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.0.1" + "peek-readable": "^4.1.0" }, "engines": { "node": ">=10" @@ -12107,6 +12490,26 @@ "graphql": ">=0.10.0" } }, + "node_modules/subscriptions-transport-ws/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12119,9 +12522,10 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -12141,6 +12545,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swap-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", + "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", @@ -12149,22 +12562,16 @@ "node": ">=0.10.0" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, "node_modules/sync-exec": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/sync-exec/-/sync-exec-0.6.2.tgz", - "integrity": "sha1-cX0izFPwzh3vVZQ2LzqJouu5EQU=", + "integrity": "sha512-FHup6L3hMWn+2asiIC/7kj/3CaMM8aAAKPx62DRk42hQkz4H2yBADR0OnnY8Eh5Bxrzb371aPUfnW4WzAUYItQ==", "optional": true }, "node_modules/systeminformation": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.11.0.tgz", - "integrity": "sha512-mI/5nFK7NUe9Qbmy65WoB5TlCWKAhP4kG0w6uR2mZM8Mpdi8b45b3hTIK3W5+kQYZnYFWeS9/O5nn5rdcSvqfA==", + "version": "5.12.12", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.12.12.tgz", + "integrity": "sha512-qg9I+JxbzkgMy1eHIs+mHqVXY+LRBWLsxhffrlDm+XfzP17Jn34tLrYjrmQs3IcR6mqfXEDpfmd97FuZ32TnaQ==", "optional": true, "os": [ "darwin", @@ -12187,48 +12594,6 @@ "url": "https://www.buymeacoffee.com/systeminfo" } }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/talawa-request-context": { - "resolved": "lib/helper_lib/talawa-request-context", - "link": true - }, "node_modules/teeny-request": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.2.0.tgz", @@ -12245,52 +12610,6 @@ "node": ">=10" } }, - "node_modules/teeny-request/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/teeny-request/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/teeny-request/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/teeny-request/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, "node_modules/teeny-request/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -12304,22 +12623,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, "engines": { "node": ">=8" }, @@ -12327,14 +12631,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/test": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/test/-/test-0.6.0.tgz", - "integrity": "sha1-WYasRF7Bd1QyJRLRBLoyyKY+k44=", - "dependencies": { - "ansi-font": "0.0.2" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -12362,56 +12658,110 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "node_modules/tinybench": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.1.tgz", + "integrity": "sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==", "dev": true, "engines": { - "node": ">=6" + "node": ">=14.0.0" } }, - "node_modules/to-regex-range": { + "node_modules/tinyspy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz", + "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/title-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", @@ -12451,18 +12801,6 @@ "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.1.1.tgz", "integrity": "sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w==" }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -12478,7 +12816,16 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } }, "node_modules/triple-beam": { "version": "1.3.0", @@ -12498,22 +12845,59 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/tsconfig-paths": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", - "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" + "node_modules/ts-log": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz", + "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==", + "dev": true + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -12536,10 +12920,27 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tsx": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.11.0.tgz", + "integrity": "sha512-q+q4xxu41+AafVwvAGqtNJ1ekPFd33ZhTMXvgIpHMqv/W89efwDRE9IyjhEAZm5iTHsshKaf1BYWSk789BrNCA==", + "dev": true, + "dependencies": { + "@esbuild-kit/cjs-loader": "^2.4.0", + "@esbuild-kit/core-utils": "^3.0.0", + "@esbuild-kit/esm-loader": "^2.5.0" + }, + "bin": { + "tsx": "dist/cli.js" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dependencies": { "safe-buffer": "^5.0.1" }, @@ -12550,7 +12951,7 @@ "node_modules/tv4": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", - "integrity": "sha1-0CDIRvrdUMhVq7JeuuzGj8EPeWM=", + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==", "engines": { "node": ">= 0.8.0" } @@ -12558,7 +12959,7 @@ "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "node_modules/tx2": { "version": "1.0.5", @@ -12570,11 +12971,12 @@ } }, "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" @@ -12590,9 +12992,9 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "engines": { "node": ">=10" @@ -12622,11 +13024,10 @@ } }, "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -12635,36 +13036,65 @@ "node": ">=4.2.0" } }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + "node_modules/ua-parser-js": { + "version": "0.7.32", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", + "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } }, "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undici": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", + "integrity": "sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg==", + "dev": true, + "dependencies": { + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=12.18" + } }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "devOptional": true, + "optional": true, "dependencies": { "crypto-random-string": "^2.0.0" }, @@ -12683,7 +13113,7 @@ "node_modules/unixify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", - "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=", + "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", "dev": true, "dependencies": { "normalize-path": "^2.1.1" @@ -12695,7 +13125,7 @@ "node_modules/unixify/node_modules/normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, "dependencies": { "remove-trailing-separator": "^1.0.1" @@ -12707,86 +13137,62 @@ "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } }, - "node_modules/update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true, - "dependencies": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" + "node": ">=8" } }, - "node_modules/update-notifier/node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" }, - "engines": { - "node": ">=10" + "bin": { + "browserslist-lint": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/update-notifier/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "tslib": "^2.0.3" } }, - "node_modules/update-notifier/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "tslib": "^2.0.3" } }, "node_modules/uri-js": { @@ -12797,22 +13203,10 @@ "punycode": "^2.1.0" } }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/util.promisify": { "version": "1.1.1", @@ -12832,7 +13226,7 @@ "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } @@ -12846,35 +13240,26 @@ "uuid": "bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^1.6.0" }, "engines": { "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/validator": { "version": "13.7.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", @@ -12894,7 +13279,7 @@ "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } @@ -12902,7 +13287,7 @@ "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "engines": [ "node >=0.6.0" ], @@ -12912,6 +13297,103 @@ "extsprintf": "^1.2.0" } }, + "node_modules/vite": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.2.tgz", + "integrity": "sha512-pLrhatFFOWO9kS19bQ658CnRYzv0WLbsPih6R+iFeEEhDOuYgYCX2rztUViMz/uy/V8cLCJvLFeiOK7RJEzHcw==", + "dev": true, + "dependencies": { + "esbuild": "^0.15.9", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "0.24.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.5.tgz", + "integrity": "sha512-zw6JhPUHtLILQDe5Q39b/SzoITkG+R7hcFjuthp4xsi6zpmfQPOZcHodZ+3bqoWl4EdGK/p1fuMiEwdxgbGLOA==", + "dev": true, + "dependencies": { + "@types/chai": "^4.3.3", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "chai": "^4.3.6", + "debug": "^4.3.4", + "local-pkg": "^0.4.2", + "strip-literal": "^0.4.2", + "tinybench": "^2.3.1", + "tinypool": "^0.3.0", + "tinyspy": "^1.0.2", + "vite": "^3.0.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.16.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, "node_modules/vizion": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz", @@ -12935,9 +13417,9 @@ } }, "node_modules/vm2": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.9.tgz", - "integrity": "sha512-xwTm7NLh/uOjARRBs8/95H0e8fT3Ukw5D/JJWhxMbhKzNh1Nu981jQKvkep9iKYNxzlVrdzD0mlBGkDKZWprlw==", + "version": "3.9.11", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", + "integrity": "sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==", "dependencies": { "acorn": "^8.7.0", "acorn-walk": "^8.2.0" @@ -12949,67 +13431,41 @@ "node": ">=6.0" } }, - "node_modules/vm2/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/vm2/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, "dependencies": { - "browser-process-hrtime": "^1.0.0" + "defaults": "^1.0.3" } }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">= 8" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "node_modules/webcrypto-core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.5.tgz", + "integrity": "sha512-gaExY2/3EHQlRNNNVSrbG2Cg94Rutl7fAaKILS1w8ZDhGxdFOaw6EbCfHIxPy9vt/xwp5o0VQAx9aySPF6hU1A==", "dev": true, "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dependencies": { - "defaults": "^1.0.3" + "@peculiar/asn1-schema": "^2.1.6", + "@peculiar/json-schema": "^1.1.12", + "asn1js": "^3.0.1", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" } }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/websocket-driver": { "version": "0.7.4", @@ -13032,25 +13488,24 @@ "node": ">=0.8.0" } }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } + "node_modules/whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", + "dev": true }, "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "engines": { + "node": ">=12" + } }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -13085,10 +13540,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, "node_modules/widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, "dependencies": { "string-width": "^4.0.0" }, @@ -13097,33 +13559,34 @@ } }, "node_modules/winston": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.5.1.tgz", - "integrity": "sha512-tbRtVy+vsSSCLcZq/8nXZaOie/S2tPXPFt4be/Q3vI/WtYwm7rrwidxVw2GRa38FIXcJ1kUM6MOZ9Jmnk3F3UA==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz", + "integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==", "dependencies": { + "@colors/colors": "1.5.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.3.2", + "logform": "^2.4.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.4.2" + "winston-transport": "^4.5.0" }, "engines": { - "node": ">= 6.4.0" + "node": ">= 12.0.0" } }, "node_modules/winston-transport": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.2.tgz", - "integrity": "sha512-9jmhltAr5ygt5usgUTQbEiw/7RYXpyUbEAFRCSicIacpUzPkrnQsQZSPGEI12aLK9Jth4zNcYJx3Cvznwrl8pw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", "dependencies": { "logform": "^2.3.2", - "readable-stream": "^3.4.0", - "triple-beam": "^1.2.0" + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" }, "engines": { "node": ">= 6.4.0" @@ -13141,6 +13604,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -13156,13 +13620,13 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "devOptional": true, + "optional": true, "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -13171,11 +13635,12 @@ } }, "node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz", + "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==", + "dev": true, "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", @@ -13194,35 +13659,23 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "devOptional": true, + "optional": true, "engines": { "node": ">=8" } }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, "node_modules/xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==", "engines": { "node": "*" } }, "node_modules/xss": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.10.tgz", - "integrity": "sha512-qmoqrRksmzqSKvgqzN0055UFWY7OKx1/9JWeRswwEVX9fCG5jcYRxa/A2DHcmZX6VJvjzHRQ2STeeVcQkrmLSw==", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", + "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", "dependencies": { "commander": "^2.20.3", "cssfilter": "0.0.10" @@ -13237,7 +13690,7 @@ "node_modules/xss-clean": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/xss-clean/-/xss-clean-0.1.1.tgz", - "integrity": "sha1-07poTYXM1SBUlj0BrWqzbWYtsaU=", + "integrity": "sha512-On99yydxoAEkHpraR7Wjg9cD6UmKfbtH2HXO1it2djid32osHL7Qr8bIu+dGYoOeKzf3ZszLfz1gwR/D7whZ2A==", "dependencies": { "xss-filters": "1.2.6" } @@ -13245,7 +13698,21 @@ "node_modules/xss-filters": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/xss-filters/-/xss-filters-1.2.6.tgz", - "integrity": "sha1-aLOQicsd/4udvIiUhIObL1B/XFU=" + "integrity": "sha512-uqgwZRpVJCDfHsRX9lDrkPyCitQYzPklmLSbajJncATZKAUd1tF1x9y2VyPNFMv8SsSWed80xorSS5qGpw3WiA==" + }, + "node_modules/xss/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } }, "node_modules/y18n": { "version": "5.0.8", @@ -13261,6 +13728,21 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true + }, "node_modules/yamljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", @@ -13274,22 +13756,35 @@ "yaml2json": "bin/yaml2json" } }, + "node_modules/yamljs/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/yamljs/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "devOptional": true, + "version": "17.6.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.1.tgz", + "integrity": "sha512-leBuCGrL4dAd6ispNOGsJlhd0uZ6Qehkbu/B9KCR+Pxa/NVdNwi+i31lo0buCm6XxhJQFshXCD0/evfV4xfoUg==", + "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { @@ -13301,24 +13796,29 @@ "node": ">=10" } }, - "node_modules/yarn": { - "version": "1.22.17", - "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.17.tgz", - "integrity": "sha512-H0p241BXaH0UN9IeH//RT82tl5PfNraVpSpEoW+ET7lmopNC61eZ+A+IDvU8FM6Go5vx162SncDL8J1ZjRBriQ==", - "hasInstallScript": true, - "bin": { - "yarn": "bin/yarn.js", - "yarnpkg": "bin/yarn.js" - }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "engines": { - "node": ">=4.0.0" + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "optional": true, + "devOptional": true, "engines": { "node": ">=10" }, @@ -13347,10 +13847,32 @@ } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@apollo/protobufjs": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", - "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.6.tgz", + "integrity": "sha512-Wqo1oSHNUj/jxmsVp4iR3I480p6qdqHikn38lKrFhfzcDJ7lwd7Ck7cHRl4JE81tWNArl77xhnG/OkZhxKBYOw==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -13390,16 +13912,16 @@ }, "dependencies": { "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==" + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==" } } }, "@apollo/utils.logger": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.0.tgz", - "integrity": "sha512-dx9XrjyisD2pOa+KsB5RcDbWIAdgC91gJfeyLCgy0ctJMjQe7yZK5kdWaWlaOoCeX0z6YI9iYlg7vMPyMpQF3Q==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-1.0.1.tgz", + "integrity": "sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==" }, "@apollo/utils.printwithreducedwhitespace": { "version": "1.1.0", @@ -13413,1042 +13935,2014 @@ "integrity": "sha512-6cM8sEOJW2LaGjL/0vHV0GtRaSekrPQR4DiywaApQlL9EdROASZU5PsQibe2MWeZCOhNrPRuHh4wDMwPsWTn8A==", "requires": {} }, - "@apollo/utils.sortast": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-1.1.0.tgz", - "integrity": "sha512-VPlTsmUnOwzPK5yGZENN069y6uUHgeiSlpEhRnLFYwYNoJHsuJq2vXVwIaSmts015WTPa2fpz1inkLYByeuRQA==", + "@apollo/utils.sortast": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-1.1.0.tgz", + "integrity": "sha512-VPlTsmUnOwzPK5yGZENN069y6uUHgeiSlpEhRnLFYwYNoJHsuJq2vXVwIaSmts015WTPa2fpz1inkLYByeuRQA==", + "requires": { + "lodash.sortby": "^4.7.0" + } + }, + "@apollo/utils.stripsensitiveliterals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-1.2.0.tgz", + "integrity": "sha512-E41rDUzkz/cdikM5147d8nfCFVKovXxKBcjvLEQ7bjZm/cg9zEcXvS6vFY8ugTubI3fn6zoqo0CyU8zT+BGP9w==", + "requires": {} + }, + "@apollo/utils.usagereporting": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-1.0.0.tgz", + "integrity": "sha512-5PL7hJMkTPmdo3oxPtigRrIyPxDk/ddrUryHPDaezL1lSFExpNzsDd2f1j0XJoHOg350GRd3LyD64caLA2PU1w==", + "requires": { + "@apollo/utils.dropunuseddefinitions": "^1.1.0", + "@apollo/utils.printwithreducedwhitespace": "^1.1.0", + "@apollo/utils.removealiases": "1.0.0", + "@apollo/utils.sortast": "^1.1.0", + "@apollo/utils.stripsensitiveliterals": "^1.2.0", + "apollo-reporting-protobuf": "^3.3.1" + } + }, + "@apollographql/apollo-tools": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.4.tgz", + "integrity": "sha512-shM3q7rUbNyXVVRkQJQseXv6bnYM3BUma/eZhwXR4xsuM+bqWnJKvW7SAfRjP7LuSCocrexa5AXhjjawNHrIlw==", + "requires": {} + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.29", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz", + "integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==", + "requires": { + "xss": "^1.0.8" + } + }, + "@apollographql/graphql-upload-8-fork": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.4.tgz", + "integrity": "sha512-lHAj/PUegYu02zza9Pg0bQQYH5I0ah1nyIzu2YIqOv41P0vu3GCBISAmQCfFHThK7N3dy7dLFPhoKcXlXRLPoQ==", + "requires": { + "@types/express": "*", + "@types/fs-capacitor": "^2.0.0", + "@types/koa": "*", + "busboy": "^0.3.1", + "fs-capacitor": "^2.0.4", + "http-errors": "^1.7.3", + "object-path": "^0.11.4" + }, + "dependencies": { + "busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "requires": { + "dicer": "0.3.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" + }, + "fs-capacitor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", + "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==" + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" + } + } + }, + "@ardatan/relay-compiler": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz", + "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==", + "dev": true, + "requires": { + "@babel/core": "^7.14.0", + "@babel/generator": "^7.14.0", + "@babel/parser": "^7.14.0", + "@babel/runtime": "^7.0.0", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.0.0", + "babel-preset-fbjs": "^3.4.0", + "chalk": "^4.0.0", + "fb-watchman": "^2.0.0", + "fbjs": "^3.0.0", + "glob": "^7.1.1", + "immutable": "~3.7.6", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "relay-runtime": "12.0.0", + "signedsource": "^1.0.0", + "yargs": "^15.3.1" + }, + "dependencies": { + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "@ardatan/sync-fetch": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz", + "integrity": "sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA==", + "dev": true, + "requires": { + "node-fetch": "^2.6.1" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", + "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "dev": true + }, + "@babel/core": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", + "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.6", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helpers": "^7.19.4", + "@babel/parser": "^7.19.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.6", + "@babel/types": "^7.19.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + } + }, + "@babel/generator": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.1.tgz", + "integrity": "sha512-u1dMdBUmA7Z0rBB97xh8pIhviK7oItYOkjbsCxTWMknyvbQRBwX7/gn4JXurRdirWMFh+ZtYARqkA6ydogVZpg==", + "dev": true, + "requires": { + "@babel/types": "^7.20.0", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dev": true, + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", + "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.19.4", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.6", + "@babel/types": "^7.19.4" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "dev": true, + "requires": { + "@babel/types": "^7.19.4" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "dev": true, + "requires": { + "@babel/types": "^7.20.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", + "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.0" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.1.tgz", + "integrity": "sha512-hp0AYxaZJhxULfM1zyp7Wgr+pSUKBcP3M+PHnSzWGdXOzg/kHWIgiUWARvubhUKGOEw3xqY4x+lyZ9ytBVcELw==", + "dev": true + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", + "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", + "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.0.tgz", + "integrity": "sha512-sXOohbpHZSk7GjxK9b3dKB7CfqUD5DwOH+DggKzOQ7TXYP+RCSbRykfjQmn/zq+rBjycVRtLf9pYhAaEJA786w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.0.tgz", + "integrity": "sha512-1dIhvZfkDVx/zn2S1aFwlruspTt4189j7fEkH0Y0VyuDM6bQt7bD6kLcz3l4IlLG+e5OReaBz9ROAbttRtUHqA==", + "dev": true, "requires": { - "lodash.sortby": "^4.7.0" + "@babel/helper-plugin-utils": "^7.19.0" } }, - "@apollo/utils.stripsensitiveliterals": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-1.2.0.tgz", - "integrity": "sha512-E41rDUzkz/cdikM5147d8nfCFVKovXxKBcjvLEQ7bjZm/cg9zEcXvS6vFY8ugTubI3fn6zoqo0CyU8zT+BGP9w==", - "requires": {} + "@babel/plugin-transform-flow-strip-types": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", + "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-flow": "^7.18.6" + } }, - "@apollo/utils.usagereporting": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-1.0.0.tgz", - "integrity": "sha512-5PL7hJMkTPmdo3oxPtigRrIyPxDk/ddrUryHPDaezL1lSFExpNzsDd2f1j0XJoHOg350GRd3LyD64caLA2PU1w==", + "@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "dev": true, "requires": { - "@apollo/utils.dropunuseddefinitions": "^1.1.0", - "@apollo/utils.printwithreducedwhitespace": "^1.1.0", - "@apollo/utils.removealiases": "1.0.0", - "@apollo/utils.sortast": "^1.1.0", - "@apollo/utils.stripsensitiveliterals": "^1.2.0", - "apollo-reporting-protobuf": "^3.3.1" - }, - "dependencies": { - "@apollo/protobufjs": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.4.tgz", - "integrity": "sha512-npVJ9NVU/pynj+SCU+fambvTneJDyCnif738DnZ7pCxdDtzeEz7WkpSIq5wNUmWm5Td55N+S2xfqZ+WP4hDLng==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - } - }, - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" - }, - "apollo-reporting-protobuf": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.2.tgz", - "integrity": "sha512-j1tx9tmkVdsLt1UPzBrvz90PdjAeKW157WxGn+aXlnnGfVjZLIRXX3x5t1NWtXvB7rVaAsLLILLtDHW382TSoQ==", - "requires": { - "@apollo/protobufjs": "1.2.4" - } - } + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@apollographql/apollo-tools": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.4.tgz", - "integrity": "sha512-shM3q7rUbNyXVVRkQJQseXv6bnYM3BUma/eZhwXR4xsuM+bqWnJKvW7SAfRjP7LuSCocrexa5AXhjjawNHrIlw==", - "requires": {} + "@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + } }, - "@apollographql/graphql-playground-html": { - "version": "1.6.27", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.27.tgz", - "integrity": "sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw==", + "@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "dev": true, "requires": { - "xss": "^1.0.8" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@apollographql/graphql-upload-8-fork": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz", - "integrity": "sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g==", + "@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "dev": true, "requires": { - "@types/express": "*", - "@types/fs-capacitor": "*", - "@types/koa": "*", - "busboy": "^0.3.1", - "fs-capacitor": "^2.0.4", - "http-errors": "^1.7.3", - "object-path": "^0.11.4" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "@babel/plugin-transform-modules-commonjs": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", + "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-simple-access": "^7.19.4" } }, - "@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", - "dev": true + "@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + } }, - "@babel/core": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", - "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.16.7", - "@babel/parser": "^7.16.12", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.10", - "@babel/types": "^7.16.8", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" - } - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/plugin-transform-parameters": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.1.tgz", + "integrity": "sha512-nDvKLrAvl+kf6BOy1UJ3MGwzzfTMgppxwiD2Jb4LO3xjYyZq30oQzDNJbCQpMdG9+j2IXHoiMrw5Cm/L6ZoxXQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" } }, - "@babel/generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", - "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", + "@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dev": true, "requires": { - "@babel/types": "^7.16.8", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "@babel/plugin-transform-react-display-name": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", "dev": true, "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "@babel/plugin-transform-react-jsx": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" } }, - "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "@babel/plugin-transform-spread": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" } }, - "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "@babel/runtime": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", + "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "regenerator-runtime": "^0.13.10" } }, - "@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true + "@babel/traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", + "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.1", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.1", + "@babel/types": "^7.20.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } }, - "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "@babel/types": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.0.tgz", + "integrity": "sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" } }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } } }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true + "@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true + "@esbuild-kit/cjs-loader": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.0.tgz", + "integrity": "sha512-DBBCiHPgL2B/elUpvCDhNHXnlZQ9sfO2uyt1OJyAXKT41beQEFY4OxZ6gwS+ZesRCbZ6JV8M7GEyOPkjv8kdIw==", + "dev": true, + "requires": { + "@esbuild-kit/core-utils": "^3.0.0", + "get-tsconfig": "^4.2.0" + } }, - "@babel/helpers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", - "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "@esbuild-kit/core-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.0.0.tgz", + "integrity": "sha512-TXmwH9EFS3DC2sI2YJWJBgHGhlteK0Xyu1VabwetMULfm3oYhbrsWV5yaSr2NTWZIgDGVLHbRf0inxbjXqAcmQ==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "esbuild": "~0.15.10", + "source-map-support": "^0.5.21" } }, - "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "@esbuild-kit/esm-loader": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.5.0.tgz", + "integrity": "sha512-ySs0qOsiwj+hsgZM9/MniGdvfa9/WzqfFuIia8/5gSUPeIQIX2/tG91QakxPFOR35VFiwTB7wCiHtiS6dc6SkA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@esbuild-kit/core-utils": "^3.0.0", + "get-tsconfig": "^4.2.0" + } + }, + "@esbuild/android-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz", + "integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz", + "integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==", + "dev": true, + "optional": true + }, + "@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "type-fest": "^0.20.2" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, - "@babel/parser": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", - "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", - "dev": true + "@fastify/busboy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.1.0.tgz", + "integrity": "sha512-Fv854f94v0CzIDllbY3i/0NJPNBRNLDawf3BTYVGCe9VrIIs3Wi7AFx24F9NzCxdf0wyx/x0Q9kEVnvDOPnlxA==", + "requires": { + "text-decoding": "^1.0.0" + } + }, + "@firebase/app-types": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.8.1.tgz", + "integrity": "sha512-p75Ow3QhB82kpMzmOntv866wH9eZ3b4+QbUY+8/DA5Zzdf1c8Nsk8B7kbFpzJt4wwHMdy5LTF5YUnoTc1JiWkw==" + }, + "@firebase/auth-interop-types": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.7.tgz", + "integrity": "sha512-yA/dTveGGPcc85JP8ZE/KZqfGQyQTBCV10THdI8HTlP1GDvNrhr//J5jAt58MlsCOaO3XmC4DqScPBbtIsR/EA==", + "requires": {} + }, + "@firebase/component": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.21.tgz", + "integrity": "sha512-12MMQ/ulfygKpEJpseYMR0HunJdlsLrwx2XcEs40M18jocy2+spyzHHEwegN3x/2/BLFBjR5247Etmz0G97Qpg==", + "requires": { + "@firebase/util": "1.7.3", + "tslib": "^2.1.0" + } + }, + "@firebase/database": { + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.13.10.tgz", + "integrity": "sha512-KRucuzZ7ZHQsRdGEmhxId5jyM2yKsjsQWF9yv0dIhlxYg0D8rCVDZc/waoPKA5oV3/SEIoptF8F7R1Vfe7BCQA==", + "requires": { + "@firebase/auth-interop-types": "0.1.7", + "@firebase/component": "0.5.21", + "@firebase/logger": "0.3.4", + "@firebase/util": "1.7.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "@firebase/database-compat": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.2.10.tgz", + "integrity": "sha512-fK+IgUUqVKcWK/gltzDU+B1xauCOfY6vulO8lxoNTkcCGlSxuTtwsdqjGkFmgFRMYjXFWWJ6iFcJ/vXahzwCtA==", + "requires": { + "@firebase/component": "0.5.21", + "@firebase/database": "0.13.10", + "@firebase/database-types": "0.9.17", + "@firebase/logger": "0.3.4", + "@firebase/util": "1.7.3", + "tslib": "^2.1.0" + } }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, + "@firebase/database-types": { + "version": "0.9.17", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.17.tgz", + "integrity": "sha512-YQm2tCZyxNtEnlS5qo5gd2PAYgKCy69tUKwioGhApCFThW+mIgZs7IeYeJo2M51i4LCixYUl+CvnOyAnb/c3XA==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@firebase/app-types": "0.8.1", + "@firebase/util": "1.7.3" } }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, + "@firebase/logger": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.4.tgz", + "integrity": "sha512-hlFglGRgZEwoyClZcGLx/Wd+zoLfGmbDkFx56mQt/jJ0XMbfPqwId1kiPl0zgdWZX+D8iH+gT6GuLPFsJWgiGw==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "tslib": "^2.1.0" } }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, + "@firebase/util": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.7.3.tgz", + "integrity": "sha512-wxNqWbqokF551WrJ9BIFouU/V5SL1oYCGx1oudcirdhadnQRFH5v1sjgGL7cUV/UsekSycygphdrF2lxBxOYKg==", "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "tslib": "^2.1.0" } }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, + "@google-cloud/firestore": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.15.1.tgz", + "integrity": "sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==", + "optional": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^2.24.1", + "protobufjs": "^6.8.6" } }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, + "@google-cloud/paginator": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz", + "integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==", + "optional": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "arrify": "^2.0.0", + "extend": "^3.0.2" } }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, + "@google-cloud/projectify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz", + "integrity": "sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==", + "optional": true + }, + "@google-cloud/promisify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.4.tgz", + "integrity": "sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==", + "optional": true + }, + "@google-cloud/storage": { + "version": "5.20.5", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.20.5.tgz", + "integrity": "sha512-lOs/dCyveVF8TkVFnFSF7IGd0CJrTm91qiK6JLu+Z8qiT+7Ag0RyVhxZIWkhiACqwABo7kSHDm8FdH8p2wxSSw==", + "optional": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@google-cloud/paginator": "^3.0.7", + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "abort-controller": "^3.0.0", + "arrify": "^2.0.0", + "async-retry": "^1.3.3", + "compressible": "^2.0.12", + "configstore": "^5.0.0", + "duplexify": "^4.0.0", + "ent": "^2.2.0", + "extend": "^3.0.2", + "gaxios": "^4.0.0", + "google-auth-library": "^7.14.1", + "hash-stream-validation": "^0.2.2", + "mime": "^3.0.0", + "mime-types": "^2.0.8", + "p-limit": "^3.0.1", + "pumpify": "^2.0.0", + "retry-request": "^4.2.2", + "stream-events": "^1.0.4", + "teeny-request": "^7.1.3", + "uuid": "^8.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true + } } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@graphql-codegen/cli": { + "version": "2.13.11", + "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-2.13.11.tgz", + "integrity": "sha512-PJF36a1i6M7Btj1kB4PWWzBUO3u2BJzsd/6KXxRmEugcxrbaCnbTDDktopy0CZYKdqaFbXaowwbRY8Tk8DV99Q==", + "dev": true, + "requires": { + "@babel/generator": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/types": "^7.18.13", + "@graphql-codegen/core": "2.6.5", + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-tools/apollo-engine-loader": "^7.3.6", + "@graphql-tools/code-file-loader": "^7.3.1", + "@graphql-tools/git-loader": "^7.2.1", + "@graphql-tools/github-loader": "^7.3.6", + "@graphql-tools/graphql-file-loader": "^7.5.0", + "@graphql-tools/json-file-loader": "^7.4.1", + "@graphql-tools/load": "7.8.0", + "@graphql-tools/prisma-loader": "^7.2.7", + "@graphql-tools/url-loader": "^7.13.2", + "@graphql-tools/utils": "^8.9.0", + "@whatwg-node/fetch": "^0.3.0", + "ansi-escapes": "^4.3.1", + "chalk": "^4.1.0", + "chokidar": "^3.5.2", + "cosmiconfig": "^7.0.0", + "cosmiconfig-typescript-loader": "4.1.1", + "debounce": "^1.2.0", + "detect-indent": "^6.0.0", + "graphql-config": "4.3.6", + "inquirer": "^8.0.0", + "is-glob": "^4.0.1", + "json-to-pretty-yaml": "^1.2.2", + "listr2": "^4.0.5", + "log-symbols": "^4.0.0", + "mkdirp": "^1.0.4", + "shell-quote": "^1.7.3", + "string-env-interpolation": "^1.0.1", + "ts-log": "^2.2.3", + "tslib": "^2.4.0", + "yaml": "^1.10.0", + "yargs": "^17.0.0" } }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "@graphql-codegen/core": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-2.6.5.tgz", + "integrity": "sha512-oSbM8vINFxcV1GUasJTDIemMpEG1t6NkBG8odQCt/3ZExCYmoviHhG9vJB89QqJeU5W06qQB6SJn/dg/gv5Aqg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-tools/schema": "^9.0.0", + "@graphql-tools/utils": "9.0.0", + "tslib": "~2.4.0" + }, + "dependencies": { + "@graphql-tools/merge": { + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", + "dev": true, + "requires": { + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } + } + }, + "@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", + "dev": true, + "requires": { + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } + } + }, + "@graphql-tools/utils": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.0.tgz", + "integrity": "sha512-kaCwyWnURxMsYbxzkfylLqFFelu83jKk3BJOOy0GIuxEtgXVS9v7Y/tojljo69Q+jaZ2YxAi3+d8IpM+hx768A==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } } }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "@graphql-codegen/plugin-helpers": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz", + "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@graphql-tools/utils": "^8.8.0", + "change-case-all": "1.0.14", + "common-tags": "1.8.2", + "import-from": "4.0.0", + "lodash": "~4.17.0", + "tslib": "~2.4.0" } }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "@graphql-codegen/schema-ast": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.5.1.tgz", + "integrity": "sha512-tewa5DEKbglWn7kYyVBkh3J8YQ5ALqAMVmZwiVFIGOao5u66nd+e4HuFqp0u+Jpz4SJGGi0ap/oFrEvlqLjd2A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@graphql-codegen/plugin-helpers": "^2.6.2", + "@graphql-tools/utils": "^8.8.0", + "tslib": "~2.4.0" } }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "@graphql-codegen/typescript": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.8.1.tgz", + "integrity": "sha512-kweV1DOOH2blvMheVL55TT0s9bxkmF/zijN9mdk9pRD20i/rI/46qbh8fNKqy/PV12vZOmZGNL6tigdghG2bqg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-codegen/schema-ast": "^2.5.1", + "@graphql-codegen/visitor-plugin-common": "2.13.1", + "auto-bind": "~4.0.0", + "tslib": "~2.4.0" } }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "@graphql-codegen/typescript-resolvers": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-resolvers/-/typescript-resolvers-2.7.6.tgz", + "integrity": "sha512-z3wX3CV3MK7o52RAqbm0qXzAY9fPg0QLPArpdRYZ4AZ4sGAZQfGaQjyFcBJnY7pVB8KIEbBY7M4HNAqSmWH6+g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-codegen/typescript": "^2.8.1", + "@graphql-codegen/visitor-plugin-common": "2.13.1", + "@graphql-tools/utils": "^8.8.0", + "auto-bind": "~4.0.0", + "tslib": "~2.4.0" } }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "@graphql-codegen/visitor-plugin-common": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.1.tgz", + "integrity": "sha512-mD9ufZhDGhyrSaWQGrU1Q1c5f01TeWtSWy/cDwXYjJcHIj1Y/DG2x0tOflEfCvh5WcnmHNIw4lzDsg1W7iFJEg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@graphql-codegen/plugin-helpers": "^2.7.2", + "@graphql-tools/optimize": "^1.3.0", + "@graphql-tools/relay-operation-optimizer": "^6.5.0", + "@graphql-tools/utils": "^8.8.0", + "auto-bind": "~4.0.0", + "change-case-all": "1.0.14", + "dependency-graph": "^0.11.0", + "graphql-tag": "^2.11.0", + "parse-filepath": "^1.0.2", + "tslib": "~2.4.0" } }, - "@babel/runtime": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", - "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", + "@graphql-eslint/eslint-plugin": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@graphql-eslint/eslint-plugin/-/eslint-plugin-3.13.0.tgz", + "integrity": "sha512-ZFWqGrSU7GnKuNRQ0omlmLikHarQ3kUf4bd3OgFte/JnyHTDeHm5M1o5L32bnHQzuuMpSXEItLy8wqqKAlrGGg==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.4" + "@babel/code-frame": "^7.18.6", + "@graphql-tools/code-file-loader": "^7.3.6", + "@graphql-tools/graphql-tag-pluck": "^7.3.6", + "@graphql-tools/utils": "^8.12.0", + "chalk": "^4.1.2", + "debug": "^4.3.4", + "fast-glob": "^3.2.12", + "graphql-config": "^4.3.6", + "graphql-depth-limit": "^1.1.0", + "lodash.lowercase": "^4.3.0" } }, - "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "@graphql-tools/apollo-engine-loader": { + "version": "7.3.17", + "resolved": "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.3.17.tgz", + "integrity": "sha512-h8rSDQDjtSElYc1vWZPIx6ZWMozSFyIN9hfGSY8kHIESU9O0ShEzs1lzRhmMmaAO75e7GxNwAjrBv/OCrxpETg==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@ardatan/sync-fetch": "0.0.1", + "@graphql-tools/utils": "9.0.1", + "@whatwg-node/fetch": "^0.5.0", + "tslib": "^2.4.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + }, + "@whatwg-node/fetch": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.5.1.tgz", + "integrity": "sha512-RBZS60EU6CbRJ370BVVKW4F9csZuGh0OQNrUDhJ0IaIFLsXsJorFCM2iwaDWZTAPMqxW1TmuVcVKJ3d/H1dV1g==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.12.0", + "web-streams-polyfill": "^3.2.0" } } } }, - "@babel/traverse": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", - "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "@graphql-tools/batch-execute": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-8.5.10.tgz", + "integrity": "sha512-f3b/UPvscQ4NaSmSQIeZPNFhpZ9xb3AftKKSn9NzsUp3vxz0d8tymBVn28f51oqiqN9BMDpCH9P8TZrKpH1//Q==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.16.10", - "@babel/types": "^7.16.8", - "debug": "^4.1.0", - "globals": "^11.1.0" + "@graphql-tools/utils": "9.0.1", + "dataloader": "2.1.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, "dependencies": { - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" - } - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "requires": { - "ms": "2.1.2" + "tslib": "^2.4.0" } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, - "@babel/types": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", - "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "@graphql-tools/code-file-loader": { + "version": "7.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-7.3.10.tgz", + "integrity": "sha512-UbEbuzhL01CvNhlesWMAo2ffRoyPRffTDlnUnkyvb6RuJkZhgY5A0k1RJYjt1uJQOkzPQLkkVKdSYqhHRkoH7g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true - }, - "@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" + "@graphql-tools/graphql-tag-pluck": "7.3.10", + "@graphql-tools/utils": "9.0.1", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } } }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "@graphql-tools/delegate": { + "version": "9.0.14", + "resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-9.0.14.tgz", + "integrity": "sha512-yKwNQl10fOdKxSk5yBoKnSjq1oumf4QYVinV9niD9KVow6j0dONtaiAYvhzaQwN/Xwwi7oADFACmKRtphlhFTw==", "dev": true, "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "@graphql-tools/batch-execute": "8.5.10", + "@graphql-tools/executor": "0.0.6", + "@graphql-tools/schema": "9.0.8", + "@graphql-tools/utils": "9.0.1", + "dataloader": "2.1.0", + "tslib": "~2.4.0", + "value-or-promise": "1.0.11" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "@graphql-tools/merge": { + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", "dev": true, "requires": { - "ms": "2.1.2" + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", + "dev": true, + "requires": { + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } } } }, - "@fastify/busboy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.1.0.tgz", - "integrity": "sha512-Fv854f94v0CzIDllbY3i/0NJPNBRNLDawf3BTYVGCe9VrIIs3Wi7AFx24F9NzCxdf0wyx/x0Q9kEVnvDOPnlxA==", - "requires": { - "text-decoding": "^1.0.0" - } - }, - "@firebase/app-types": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", - "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" - }, - "@firebase/auth-interop-types": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", - "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", - "requires": {} - }, - "@firebase/component": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.15.tgz", - "integrity": "sha512-VRnZxmvtJmXupTPg37LxM0zdyMN54EXkmsFD4x5Bm4eZUay9VGnhfiGnE3m9Af/2hnURA2idIBN/23L6982iPQ==", - "requires": { - "@firebase/util": "1.6.1", - "tslib": "^2.1.0" - } - }, - "@firebase/database": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.13.1.tgz", - "integrity": "sha512-k6PeAzf9x9DG3AJtA6SkJsTD1ivOWvrV71VPOYabBch05QDB0HOYs1EauGhzqa6GOcYz+ncb4pNEkgFDvcnEfQ==", + "@graphql-tools/executor": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-0.0.6.tgz", + "integrity": "sha512-2KIj1grRb1Lni97xgX1ryekcjU/WTMC1ZdPpnd0nYrBWs/C4Nv4UMNP7E/Tr8za8zlrsESvEUbpLHsBRiQsGxA==", + "dev": true, "requires": { - "@firebase/auth-interop-types": "0.1.6", - "@firebase/component": "0.5.15", - "@firebase/logger": "0.3.3", - "@firebase/util": "1.6.1", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - } - }, - "@firebase/database-compat": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.2.1.tgz", - "integrity": "sha512-xpru5ZtO7um2FmfIw4gCAbkWpyOEwxzamU/5phuwze3ZihMdh+UrDrwrhvfqzQ/KIKXsK76Uyx5F3NCAS8+5eg==", - "requires": { - "@firebase/component": "0.5.15", - "@firebase/database": "0.13.1", - "@firebase/database-types": "0.9.9", - "@firebase/logger": "0.3.3", - "@firebase/util": "1.6.1", - "tslib": "^2.1.0" + "@graphql-tools/utils": "9.0.1", + "@graphql-typed-document-node/core": "3.1.1", + "@repeaterjs/repeater": "3.0.4", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } } }, - "@firebase/database-types": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.9.tgz", - "integrity": "sha512-Zp86fHzQFZKYVM7yDWVAgVTeOJ39g2wT0ijeiN0jpHAHceeoV013q3jPIIGuooV2HMwWOTIBZGqh+DxrHMFyUw==", + "@graphql-tools/git-loader": { + "version": "7.2.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-7.2.10.tgz", + "integrity": "sha512-y27w+7I5LmOXzz4EI3XHR+ZM2rZJquHnPAiEXLIt5Nh+9Z0frqtb4AJma3gAeRKROcKg5VN/Bx/ehp68S48lHw==", + "dev": true, "requires": { - "@firebase/app-types": "0.7.0", - "@firebase/util": "1.6.1" + "@graphql-tools/graphql-tag-pluck": "7.3.10", + "@graphql-tools/utils": "9.0.1", + "is-glob": "4.0.3", + "micromatch": "^4.0.4", + "tslib": "^2.4.0", + "unixify": "^1.0.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } } }, - "@firebase/logger": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.3.tgz", - "integrity": "sha512-POTJl07jOKTOevLXrTvJD/VZ0M6PnJXflbAh5J9VGkmtXPXNG6MdZ9fmRgqYhXKTaDId6AQenQ262uwgpdtO0Q==", + "@graphql-tools/github-loader": { + "version": "7.3.17", + "resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-7.3.17.tgz", + "integrity": "sha512-JstgZUnifz2lQAk/mw7gq1uPSr5bG+7nw3IXZmUKOU+8zBjmFugRVWxLtJ1/bxZzqnhmYlC7nBqt1Ej1Tn5qKA==", + "dev": true, "requires": { - "tslib": "^2.1.0" + "@ardatan/sync-fetch": "0.0.1", + "@graphql-tools/graphql-tag-pluck": "7.3.10", + "@graphql-tools/utils": "9.0.1", + "@whatwg-node/fetch": "^0.5.0", + "tslib": "^2.4.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + }, + "@whatwg-node/fetch": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.5.1.tgz", + "integrity": "sha512-RBZS60EU6CbRJ370BVVKW4F9csZuGh0OQNrUDhJ0IaIFLsXsJorFCM2iwaDWZTAPMqxW1TmuVcVKJ3d/H1dV1g==", + "dev": true, + "requires": { + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.12.0", + "web-streams-polyfill": "^3.2.0" + } + } } }, - "@firebase/util": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.6.1.tgz", - "integrity": "sha512-+eDE6uG5GgvXYHbAzfP1mpJUX1VDBD+A8CjBeBoNAKAVAApMSDxDODqRcOq7NW7kFJXSUkMzDJWhnUIifX2R8w==", + "@graphql-tools/graphql-file-loader": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.5.9.tgz", + "integrity": "sha512-hEvWFLOG8JGsguWWdHqaFvj0xqwQu4KhqAKEjmIBq4vipVKLcmcjvOM56S0fv/dtn5pcKp9ZOZAxgncYVJ1hzw==", + "dev": true, "requires": { - "tslib": "^2.1.0" + "@graphql-tools/import": "6.7.10", + "@graphql-tools/utils": "9.0.1", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } } }, - "@google-cloud/firestore": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.15.1.tgz", - "integrity": "sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==", - "optional": true, + "@graphql-tools/graphql-tag-pluck": { + "version": "7.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.3.10.tgz", + "integrity": "sha512-A3FHMbi90NHWTIzrwnbI0kHwCWfSL8j7zXuuIZKL009V+M8K0DPg/+ZCy/4SQB14yl/NTz5ZQ/0GXffD3qvMDg==", + "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^2.24.1", - "protobufjs": "^6.8.6" + "@babel/parser": "^7.16.8", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } } }, - "@google-cloud/paginator": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz", - "integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==", - "optional": true, + "@graphql-tools/import": { + "version": "6.7.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-6.7.10.tgz", + "integrity": "sha512-6L19Ep0pP5wWywq9/jwCt2FdCJnEnyrxkmRkSRdYoTEmOFz5xrsfhyUfWl8ibx34gWzVYhCDOX1bN43zsLCbDA==", + "dev": true, "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" + "@graphql-tools/utils": "9.0.1", + "resolve-from": "5.0.0", + "tslib": "^2.4.0" }, "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } } } }, - "@google-cloud/projectify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz", - "integrity": "sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==", - "optional": true - }, - "@google-cloud/promisify": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.4.tgz", - "integrity": "sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==", - "optional": true - }, - "@google-cloud/storage": { - "version": "5.20.5", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.20.5.tgz", - "integrity": "sha512-lOs/dCyveVF8TkVFnFSF7IGd0CJrTm91qiK6JLu+Z8qiT+7Ag0RyVhxZIWkhiACqwABo7kSHDm8FdH8p2wxSSw==", - "optional": true, + "@graphql-tools/json-file-loader": { + "version": "7.4.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-7.4.10.tgz", + "integrity": "sha512-/njUvIW/zdSr70eWDfDQNDXp2UQLe+YKFRLMZkpuISrw5cdvGaMepwpr0Yz6kFnHGwB6wSYLH25LkRAzpiKz+g==", + "dev": true, "requires": { - "@google-cloud/paginator": "^3.0.7", - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "abort-controller": "^3.0.0", - "arrify": "^2.0.0", - "async-retry": "^1.3.3", - "compressible": "^2.0.12", - "configstore": "^5.0.0", - "duplexify": "^4.0.0", - "ent": "^2.2.0", - "extend": "^3.0.2", - "gaxios": "^4.0.0", - "google-auth-library": "^7.14.1", - "hash-stream-validation": "^0.2.2", - "mime": "^3.0.0", - "mime-types": "^2.0.8", - "p-limit": "^3.0.1", - "pumpify": "^2.0.0", - "retry-request": "^4.2.2", - "stream-events": "^1.0.4", - "teeny-request": "^7.1.3", - "uuid": "^8.0.0", - "xdg-basedir": "^4.0.0" + "@graphql-tools/utils": "9.0.1", + "globby": "^11.0.3", + "tslib": "^2.4.0", + "unixify": "^1.0.0" }, "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true - }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "optional": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "optional": true, + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, "requires": { - "yocto-queue": "^0.1.0" + "tslib": "^2.4.0" } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true } } }, - "@graphql-toolkit/common": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@graphql-toolkit/common/-/common-0.10.4.tgz", - "integrity": "sha512-HQ3HaxCqX+UE8y/0h7LMDBBGSIKJxY/gaQesaksvE2Y+N4NpSWdiW6HpOcgXfC2HGf9yM0hEdsERzzL8z3mbHQ==", + "@graphql-tools/load": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-7.8.0.tgz", + "integrity": "sha512-l4FGgqMW0VOqo+NMYizwV8Zh+KtvVqOf93uaLo9wJ3sS3y/egPCgxPMDJJ/ufQZG3oZ/0oWeKt68qop3jY0yZg==", "dev": true, "requires": { - "aggregate-error": "3.0.1", - "camel-case": "4.1.1", - "graphql-tools": "5.0.0", - "lodash": "4.17.15" + "@graphql-tools/schema": "9.0.4", + "@graphql-tools/utils": "8.12.0", + "p-limit": "3.1.0", + "tslib": "^2.4.0" }, "dependencies": { - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "@graphql-tools/merge": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.6.tgz", + "integrity": "sha512-uUBokxXi89bj08P+iCvQk3Vew4vcfL5ZM6NTylWi8PIpoq4r5nJ625bRuN8h2uubEdRiH8ntN9M4xkd/j7AybQ==", "dev": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@graphql-tools/utils": "8.12.0", + "tslib": "^2.4.0" } }, - "graphql-tools": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-5.0.0.tgz", - "integrity": "sha512-5zn3vtn//382b7G3Wzz3d5q/sh+f7tVrnxeuhTMTJ7pWJijNqLxH7VEzv8VwXCq19zAzHYEosFHfXiK7qzvk7w==", + "@graphql-tools/schema": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.4.tgz", + "integrity": "sha512-B/b8ukjs18fq+/s7p97P8L1VMrwapYc3N2KvdG/uNThSazRRn8GsBK0Nr+FH+mVKiUfb4Dno79e3SumZVoHuOQ==", "dev": true, "requires": { - "apollo-link": "^1.2.14", - "apollo-upload-client": "^13.0.0", - "deprecated-decorator": "^0.1.6", - "form-data": "^3.0.0", - "iterall": "^1.3.0", - "node-fetch": "^2.6.0", - "tslib": "^1.11.1", - "uuid": "^7.0.3" + "@graphql-tools/merge": "8.3.6", + "@graphql-tools/utils": "8.12.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "@graphql-tools/utils": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.12.0.tgz", + "integrity": "sha512-TeO+MJWGXjUTS52qfK4R8HiPoF/R7X+qmgtOYd8DTH0l6b+5Y/tlg5aGeUJefqImRq7nvi93Ms40k/Uz4D5CWw==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } + } + }, + "@graphql-tools/merge": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz", + "integrity": "sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg==", + "requires": { + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", + "requires": { + "tslib": "^2.4.0" + } + } + } + }, + "@graphql-tools/mock": { + "version": "8.7.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.7.10.tgz", + "integrity": "sha512-PuRGfk6TQger7EfE08yO3+QCAcZ6nYo3kyoEmTPc27w4yiqKCwZIyD8vegzl/EQphEourjaOhO149te6qNEUeQ==", + "requires": { + "@graphql-tools/schema": "9.0.8", + "@graphql-tools/utils": "9.0.1", + "fast-json-stable-stringify": "^2.1.0", + "tslib": "^2.4.0" + }, + "dependencies": { + "@graphql-tools/merge": { + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", + "requires": { + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" + } }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", + "requires": { + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" + } }, - "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", - "dev": true + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "requires": { + "tslib": "^2.4.0" + } } } }, - "@graphql-toolkit/file-loading": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@graphql-toolkit/file-loading/-/file-loading-0.10.4.tgz", - "integrity": "sha512-oUmy/sO3BJfax85pVKI7FZ6TWrViNuWXoJkRM293YV9bKGuYU9TgqZoHyM+oEqWO5ruXCL/nCdw3cIBau+rSNA==", + "@graphql-tools/optimize": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.3.1.tgz", + "integrity": "sha512-5j5CZSRGWVobt4bgRRg7zhjPiSimk+/zIuColih8E8DxuFOaJ+t0qu7eZS5KXWBkjcd4BPNuhUPpNlEmHPqVRQ==", "dev": true, "requires": { - "globby": "11.0.0", - "unixify": "1.0.0" + "tslib": "^2.4.0" } }, - "@graphql-toolkit/schema-merging": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@graphql-toolkit/schema-merging/-/schema-merging-0.10.4.tgz", - "integrity": "sha512-naL6reYBuILLMrkMfKz0lOLL0kl6gGYnaaywnO/Dgp9F4NeAxDdAs5CV6Fy9NO5OzePFP58Dnc4sh2RyYrrFJg==", + "@graphql-tools/prisma-loader": { + "version": "7.2.30", + "resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-7.2.30.tgz", + "integrity": "sha512-EmYC6ltX2TxOKPgiqdVZctm3uyXdwo53GBwWNyOTIx+8hczrF9LO59LGwNtuy+GsT5A1ZK93og7F+8zztkCFIw==", "dev": true, "requires": { - "@graphql-toolkit/common": "0.10.4", - "deepmerge": "4.2.2", - "graphql-tools": "5.0.0", - "tslib": "1.11.1" + "@graphql-tools/url-loader": "7.16.10", + "@graphql-tools/utils": "9.0.1", + "@types/js-yaml": "^4.0.0", + "@types/json-stable-stringify": "^1.0.32", + "@types/jsonwebtoken": "^8.5.0", + "chalk": "^4.1.0", + "debug": "^4.3.1", + "dotenv": "^16.0.0", + "graphql-request": "^5.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "isomorphic-fetch": "^3.0.0", + "js-yaml": "^4.0.0", + "json-stable-stringify": "^1.0.1", + "jsonwebtoken": "^8.5.1", + "lodash": "^4.17.20", + "scuid": "^1.1.0", + "tslib": "^2.4.0", + "yaml-ast-parser": "^0.0.43" }, "dependencies": { - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "graphql-tools": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-5.0.0.tgz", - "integrity": "sha512-5zn3vtn//382b7G3Wzz3d5q/sh+f7tVrnxeuhTMTJ7pWJijNqLxH7VEzv8VwXCq19zAzHYEosFHfXiK7qzvk7w==", + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", "dev": true, "requires": { - "apollo-link": "^1.2.14", - "apollo-upload-client": "^13.0.0", - "deprecated-decorator": "^0.1.6", - "form-data": "^3.0.0", - "iterall": "^1.3.0", - "node-fetch": "^2.6.0", - "tslib": "^1.11.1", - "uuid": "^7.0.3" + "tslib": "^2.4.0" } }, - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true - }, - "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "dev": true } } }, - "@graphql-tools/merge": { - "version": "6.2.17", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-6.2.17.tgz", - "integrity": "sha512-G5YrOew39fZf16VIrc49q3c8dBqQDD0ax5LYPiNja00xsXDi0T9zsEWVt06ApjtSdSF6HDddlu5S12QjeN8Tow==", + "@graphql-tools/relay-operation-optimizer": { + "version": "6.5.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.5.10.tgz", + "integrity": "sha512-daNJRkJa/NgpXVxUApCMIGqHoyHExaG7XN2gk48r+DbKmoahpflF+lnhBKmS44HtSGciFUv8bPbp0NWvXafZ2w==", "dev": true, "requires": { - "@graphql-tools/schema": "^8.0.2", - "@graphql-tools/utils": "8.0.2", - "tslib": "~2.3.0" + "@ardatan/relay-compiler": "12.0.0", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + } } }, - "@graphql-tools/mock": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.6.3.tgz", - "integrity": "sha512-Nv095DXWz5Xt6U3SHhkIVtfuWyBNW1yiQk1o+DgM8/4Vj+v6zic1/y3eUpmoiy/qKu3qgagA6mxI8ZU/W6VS8w==", + "@graphql-tools/schema": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz", + "integrity": "sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==", "requires": { - "@graphql-tools/schema": "8.3.5", - "@graphql-tools/utils": "8.6.5", - "fast-json-stable-stringify": "^2.1.0", - "tslib": "~2.3.0" + "@graphql-tools/merge": "8.3.1", + "@graphql-tools/utils": "8.9.0", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" }, "dependencies": { "@graphql-tools/utils": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz", - "integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==", "requires": { - "tslib": "~2.3.0" + "tslib": "^2.4.0" } } } }, - "@graphql-tools/schema": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.5.tgz", - "integrity": "sha512-3mJ/K7TdL+fnEUtCUqF4qkh1fcNMzaxgwKgO9fSYSTS7zyT16hbi5XSulSTshygHgaD2u+MO588iR4ZJcbZcIg==", + "@graphql-tools/url-loader": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-7.16.10.tgz", + "integrity": "sha512-VFf0lKZpPSFtUl3cNycBEWlB8NzJhXFfas0PYsFmzzOmtGcHeY3rY2KMUfBr4wq7chPfBbGpcuAwjiI3x9MZzg==", + "dev": true, + "requires": { + "@ardatan/sync-fetch": "0.0.1", + "@graphql-tools/delegate": "9.0.14", + "@graphql-tools/utils": "9.0.1", + "@graphql-tools/wrap": "9.2.9", + "@types/ws": "^8.0.0", + "@whatwg-node/fetch": "^0.5.0", + "dset": "^3.1.2", + "extract-files": "^11.0.0", + "graphql-ws": "^5.4.1", + "isomorphic-ws": "^5.0.0", + "meros": "^1.1.4", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.11", + "ws": "^8.3.0" + }, + "dependencies": { + "@graphql-tools/utils": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + }, + "@whatwg-node/fetch": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.5.1.tgz", + "integrity": "sha512-RBZS60EU6CbRJ370BVVKW4F9csZuGh0OQNrUDhJ0IaIFLsXsJorFCM2iwaDWZTAPMqxW1TmuVcVKJ3d/H1dV1g==", + "dev": true, + "requires": { + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.12.0", + "web-streams-polyfill": "^3.2.0" + } + } + } + }, + "@graphql-tools/utils": { + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz", + "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==", + "dev": true, + "requires": { + "tslib": "^2.4.0" + } + }, + "@graphql-tools/wrap": { + "version": "9.2.9", + "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-9.2.9.tgz", + "integrity": "sha512-GiEMy7VJIKxdgb9E8ZkaAPhePsDbBP5rOj07tr6jzcDY+ZhLcjmD9UuiPGVFgBSu6AzRyoviEJgI0hjksqfl1A==", + "dev": true, "requires": { - "@graphql-tools/merge": "8.2.6", - "@graphql-tools/utils": "8.6.5", - "tslib": "~2.3.0", + "@graphql-tools/delegate": "9.0.14", + "@graphql-tools/schema": "9.0.8", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", "value-or-promise": "1.0.11" }, "dependencies": { "@graphql-tools/merge": { - "version": "8.2.6", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.6.tgz", - "integrity": "sha512-dkwTm4czMISi/Io47IVvq2Fl9q4TIGKpJ0VZjuXYdEFkECyH6A5uwxZfPVandZG+gQs8ocFFoa6RisiUJLZrJw==", + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.10.tgz", + "integrity": "sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==", + "dev": true, + "requires": { + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0" + } + }, + "@graphql-tools/schema": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.8.tgz", + "integrity": "sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==", + "dev": true, "requires": { - "@graphql-tools/utils": "8.6.5", - "tslib": "~2.3.0" + "@graphql-tools/merge": "8.3.10", + "@graphql-tools/utils": "9.0.1", + "tslib": "^2.4.0", + "value-or-promise": "1.0.11" } }, "@graphql-tools/utils": { - "version": "8.6.5", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz", - "integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.0.1.tgz", + "integrity": "sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==", + "dev": true, "requires": { - "tslib": "~2.3.0" + "tslib": "^2.4.0" } } } }, - "@graphql-tools/utils": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.0.2.tgz", - "integrity": "sha512-gzkavMOgbhnwkHJYg32Adv6f+LxjbQmmbdD5Hty0+CWxvaiuJq+nU6tzb/7VSU4cwhbNLx/lGu2jbCPEW1McZQ==", + "@graphql-typed-document-node/core": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz", + "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==", "dev": true, - "requires": { - "tslib": "~2.3.0" - } + "requires": {} }, "@grpc/grpc-js": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz", - "integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==", + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.12.tgz", + "integrity": "sha512-JmvQ03OTSpVd9JTlj/K3IWHSz4Gk/JMLUTtW7Zb0KvO1LcOYGATh5cNuRYzCAeDR3O8wq+q8FZe97eO9MBrkUw==", "optional": true, "requires": { - "@grpc/proto-loader": "^0.6.4", + "@grpc/proto-loader": "^0.7.0", "@types/node": ">=12.12.47" + }, + "dependencies": { + "@grpc/proto-loader": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.3.tgz", + "integrity": "sha512-5dAvoZwna2Py3Ef96Ux9jIkp3iZ62TUsV00p3wVBPNX5K178UbNi8Q7gQVqwXT1Yq9RejIGG9G2IPEo93T6RcA==", + "optional": true, + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^7.0.0", + "yargs": "^16.2.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "optional": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "protobufjs": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.1.2.tgz", + "integrity": "sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ==", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "dependencies": { + "long": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", + "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==", + "optional": true + } + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "optional": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } } }, "@grpc/proto-loader": { @@ -14462,111 +15956,64 @@ "long": "^4.0.0", "protobufjs": "^6.11.3", "yargs": "^16.2.0" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "optional": true, "requires": { - "ms": "2.1.2" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "optional": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } } } }, + "@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } + "@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true }, "@istanbuljs/schema": { "version": "0.1.3", @@ -14574,202 +16021,50 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "@jest/console": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", - "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", - "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", - "dev": true, - "requires": { - "@jest/console": "^27.4.6", - "@jest/reporters": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.4.2", - "jest-config": "^27.4.7", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-resolve-dependencies": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "jest-watcher": "^27.4.6", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", - "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6" - } - }, - "@jest/fake-timers": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", - "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" - } - }, - "@jest/globals": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", - "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/types": "^27.4.2", - "expect": "^27.4.6" - } + "@josephg/resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", + "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" }, - "@jest/reporters": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", - "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - } - }, - "@jest/source-map": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", - "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "@jest/test-result": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", - "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", - "dev": true, - "requires": { - "@jest/console": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true }, - "@jest/test-sequencer": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", - "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-runtime": "^27.4.6" - } + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true }, - "@jest/transform": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", - "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, - "@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@josephg/resolvable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", - "integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==" - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -14806,6 +16101,13 @@ "semver": "^5.5.0", "shimmer": "^1.2.0", "uuid": "^3.2.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, "@opencensus/propagation-b3": { @@ -14828,6 +16130,11 @@ "shimmer": "^1.2.0", "uuid": "^3.2.1" } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -14836,6 +16143,39 @@ "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" }, + "@peculiar/asn1-schema": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.0.tgz", + "integrity": "sha512-DtNLAG4vmDrdSJFPe7rypkcj597chNQL7u+2dBtYo5mh7VW2+im6ke+O0NVr8W1f4re4C3F71LhoMb0Yxqa48Q==", + "dev": true, + "requires": { + "asn1js": "^3.0.5", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" + } + }, + "@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "dev": true, + "requires": { + "tslib": "^2.0.0" + } + }, + "@peculiar/webcrypto": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.1.tgz", + "integrity": "sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==", + "dev": true, + "requires": { + "@peculiar/asn1-schema": "^2.3.0", + "@peculiar/json-schema": "^1.1.12", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.1", + "webcrypto-core": "^1.7.4" + } + }, "@pm2/agent": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.1.tgz", @@ -14865,18 +16205,10 @@ "supports-color": "^7.1.0" } }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "dayjs": { + "version": "1.8.36", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", + "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" }, "semver": { "version": "7.2.3", @@ -14916,28 +16248,10 @@ "lodash": "^4.17.14" } }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, "eventemitter2": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", - "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" }, "tslib": { "version": "1.9.3", @@ -14966,30 +16280,31 @@ "lodash": "^4.17.14" } }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, "eventemitter2": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", - "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} } } }, + "@pm2/pm2-version-check": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", + "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", + "requires": { + "debug": "^4.3.1" + } + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "@protobufjs/base64": { "version": "1.1.2", @@ -15004,12 +16319,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -15018,70 +16333,68 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "@repeaterjs/repeater": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", + "integrity": "sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==", "dev": true }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, "@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "devOptional": true + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true }, "@types/accepts": { "version": "1.3.5", @@ -15091,51 +16404,16 @@ "@types/node": "*" } }, - "@types/babel__core": { - "version": "7.1.18", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", - "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } + "@types/bcryptjs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", + "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "dev": true }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "requires": { "@types/connect": "*", "@types/node": "*" @@ -15149,6 +16427,30 @@ "@types/node": "*" } }, + "@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", + "dev": true + }, + "@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, + "@types/cls-hooked": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/cls-hooked/-/cls-hooked-4.3.3.tgz", + "integrity": "sha512-gNstDTb/ty5h6gJd6YpSPgsLX9LmRpaKJqGFp7MRlYxhwp4vXXKlJ9+bt1TZ9KbVNXE+Mbxy2AYXcpY21DDtJw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -15158,9 +16460,9 @@ } }, "@types/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==" + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz", + "integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==" }, "@types/cookies": { "version": "0.7.7", @@ -15173,15 +16475,21 @@ "@types/node": "*" } }, + "@types/copy-paste": { + "version": "1.1.30", + "resolved": "https://registry.npmjs.org/@types/copy-paste/-/copy-paste-1.1.30.tgz", + "integrity": "sha512-/pjP3jEYc+JFXjNMjlJaSE7ZVpPYCUz0+jdF1nVzFOsEygxTt0Jr9k3DbfKV3CDfZLjFpJ5p/B+vNLxWVe9Cvw==", + "dev": true + }, "@types/cors": { "version": "2.8.10", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==" }, "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -15189,10 +16497,19 @@ "@types/serve-static": "*" } }, + "@types/express-rate-limit": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/express-rate-limit/-/express-rate-limit-5.1.3.tgz", + "integrity": "sha512-H+TYy3K53uPU2TqPGFYaiWc2xJV6+bIFkDd/Ma2/h67Pa6ARk9kWE0p/K9OH1Okm0et9Sfm66fmXoAxsH2PHXg==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -15207,13 +16524,24 @@ "@types/node": "*" } }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "@types/graphql-depth-limit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/graphql-depth-limit/-/graphql-depth-limit-1.1.3.tgz", + "integrity": "sha512-fvK0qXNvwKD5bSnMEkidi51EloYsz/E8JG/8Kzq1peoLRQAEGgLVauE1xGeT4W/nbSpecgG+34dcKPdwfGzFHQ==", "dev": true, "requires": { - "@types/node": "*" + "graphql": "^14.5.3" + }, + "dependencies": { + "graphql": { + "version": "14.7.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", + "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", + "dev": true, + "requires": { + "iterall": "^1.2.2" + } + } } }, "@types/http-assert": { @@ -15222,9 +16550,15 @@ "integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==" }, "@types/http-errors": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.2.tgz", - "integrity": "sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==" + }, + "@types/i18n": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/@types/i18n/-/i18n-0.13.5.tgz", + "integrity": "sha512-pEtMt7iBkPBFMcB4TG6NuJIz/3Osp530o3R/3Qci94d59J4ienHyWnC7/AKUoTWqqnK0nG6gd6I2g8aOGdlwIg==", + "dev": true }, "@types/istanbul-lib-coverage": { "version": "2.0.4", @@ -15232,40 +16566,28 @@ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } + "@types/js-yaml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", + "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", + "dev": true }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "@types/json-stable-stringify": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz", + "integrity": "sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw==", "dev": true }, "@types/jsonwebtoken": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz", - "integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==", + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", + "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", "requires": { "@types/node": "*" } @@ -15276,9 +16598,9 @@ "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==" }, "@types/koa": { - "version": "2.13.4", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.4.tgz", - "integrity": "sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw==", + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.5.tgz", + "integrity": "sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==", "requires": { "@types/accepts": "*", "@types/content-disposition": "*", @@ -15298,15 +16620,21 @@ "@types/koa": "*" } }, + "@types/lodash": { + "version": "4.14.187", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.187.tgz", + "integrity": "sha512-MrO/xLXCaUgZy3y96C/iOsaIqZSeupyTImKClHunL5GrmaiII2VwvWmLBu2hwa0Kp0sV19CsyjtrTc/Fx8rg/A==", + "dev": true + }, "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "@types/mongodb": { "version": "3.6.20", @@ -15317,15 +16645,42 @@ "@types/node": "*" } }, + "@types/mongoose-paginate-v2": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@types/mongoose-paginate-v2/-/mongoose-paginate-v2-1.6.5.tgz", + "integrity": "sha512-OdnsqewLwCtZvExUHuL+KDVlZ6OdnzGcUdPpEqMRVKZ6mWy7fgnt1IkLSs8Zugv5cUTLVT46hjmL2OPWtml1Rw==", + "dev": true, + "requires": { + "mongoose-paginate-v2": "*" + } + }, + "@types/morgan": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz", + "integrity": "sha512-BiLcfVqGBZCyNCnCH3F4o2GmDLrpy0HeBVnNlyZG4fo88ZiE9SoiBe3C+2ezuwbjlEyT+PDZ17//TAlRxAn75Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/node": { - "version": "17.0.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.14.tgz", - "integrity": "sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng==" + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" }, - "@types/prettier": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", - "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", + "@types/nodemailer": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.6.tgz", + "integrity": "sha512-pD6fL5GQtUKvD2WnPmg5bC2e8kWCAPDwMPmHe/ohQbW+Dy0EcHgZ2oCSuPlWNqk74LS5BVMig1SymQbFMPPK3w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, "@types/qs": { @@ -15338,133 +16693,162 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, "@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", "requires": { - "@types/mime": "^1", + "@types/mime": "*", "@types/node": "*" } }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "@types/shortid": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/shortid/-/shortid-0.0.29.tgz", + "integrity": "sha512-9BCYD9btg2CY4kPcpMQ+vCR8U6V8f/KvixYD5ZbxoWlkhddNF5IeZMVL3p+QFUkg+Hb+kPAG9Jgk4bnnF1v/Fw==", "dev": true }, - "@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "requires": { - "@types/node": "*" - } + "@types/uuid": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", + "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==", + "dev": true + }, + "@types/validator": { + "version": "13.7.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.10.tgz", + "integrity": "sha512-t1yxFAR2n0+VO6hd/FJ9F2uezAZVWHLmpmlJzm1eX03+H7+HsuTAp7L8QJs+2pQCfWkP1+EXsGK9Z9v7o/qPVQ==", + "dev": true }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", "dev": true, "requires": { - "@types/yargs-parser": "*" + "@types/node": "*" } }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "@typescript-eslint/eslint-plugin": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.0.tgz", + "integrity": "sha512-5TJh2AgL6+wpL8H/GTSjNb4WrjKoR2rqvFxR/DDTqYNk6uXn8BJMEcncLSpMbf/XV1aS0jAjYwn98uvVCiAywQ==", "dev": true, "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@typescript-eslint/scope-manager": "5.42.0", + "@typescript-eslint/type-utils": "5.42.0", + "@typescript-eslint/utils": "5.42.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { - "eslint-visitor-keys": "^2.0.0" + "lru-cache": "^6.0.0" } } } }, + "@typescript-eslint/parser": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.0.tgz", + "integrity": "sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.42.0", + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/typescript-estree": "5.42.0", + "debug": "^4.3.4" + } + }, "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.0.tgz", + "integrity": "sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==", "dev": true, "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/visitor-keys": "5.42.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.0.tgz", + "integrity": "sha512-HW14TXC45dFVZxnVW8rnUGnvYyRC0E/vxXShFCthcC9VhVTmjqOmtqj6H5rm9Zxv+ORxKA/1aLGD7vmlLsdlOg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.42.0", + "@typescript-eslint/utils": "5.42.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.0.tgz", + "integrity": "sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.0.tgz", + "integrity": "sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/visitor-keys": "5.42.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "lru-cache": "^6.0.0" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, + } + } + }, + "@typescript-eslint/utils": { + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.0.tgz", + "integrity": "sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.42.0", + "@typescript-eslint/types": "5.42.0", + "@typescript-eslint/typescript-estree": "5.42.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + }, + "dependencies": { "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -15473,13 +16857,40 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "version": "5.42.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.0.tgz", + "integrity": "sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" + "@typescript-eslint/types": "5.42.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@vitest/coverage-c8": { + "version": "0.24.5", + "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.24.5.tgz", + "integrity": "sha512-955yK/SdSBZPYrSXgXB0F+0JnOX5EY9kSL7ywJ4rNajmkFUhwLjuKm13Xb6YKSyIY/g5WvbBnyowqfNRxBJ3ww==", + "dev": true, + "requires": { + "c8": "^7.12.0", + "vitest": "0.24.5" + } + }, + "@whatwg-node/fetch": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.3.2.tgz", + "integrity": "sha512-Bs5zAWQs0tXsLa4mRmLw7Psps1EN78vPtgcLpw3qPY8s6UYPUM67zFZ9cy+7tZ64PXhfwzxJn+m7RH2Lq48RNQ==", + "dev": true, + "requires": { + "@peculiar/webcrypto": "^1.4.0", + "abort-controller": "^3.0.0", + "busboy": "^1.6.0", + "event-target-polyfill": "^0.0.3", + "form-data-encoder": "^1.7.1", + "formdata-node": "^4.3.1", + "node-fetch": "^2.6.7", + "undici": "^5.8.0", + "web-streams-polyfill": "^3.2.0" } }, "@wry/equality": { @@ -15497,51 +16908,28 @@ } } }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "optional": true, + "devOptional": true, "requires": { "event-target-shim": "^5.0.0" } }, "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" }, "acorn-jsx": { "version": "5.3.2", @@ -15551,10 +16939,9 @@ "requires": {} }, "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, "agent-base": { "version": "6.0.2", @@ -15562,27 +16949,12 @@ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "requires": { "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { "clean-stack": "^2.0.0", @@ -15603,12 +16975,12 @@ "amp": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", - "integrity": "sha1-at+NWKdPNh6CwfqNOJwHnhOfxH0=" + "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==" }, "amp-message": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", - "integrity": "sha1-p48cmJlQh602GSpBKY5NtJ49/EU=", + "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==", "requires": { "amp": "0.3.1" } @@ -15617,39 +16989,30 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, "requires": { "string-width": "^4.1.0" } }, "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==" }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, "requires": { "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - } } }, - "ansi-font": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ansi-font/-/ansi-font-0.0.2.tgz", - "integrity": "sha1-iQMBvVhBRi/TnAt3Ca/R9SUUMzE=" - }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true }, "ansi-styles": { "version": "4.3.0", @@ -15657,27 +17020,13 @@ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { "color-convert": "^2.0.1" - }, - "dependencies": { - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - } } }, "ansicolors": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true }, "anymatch": { "version": "3.1.2", @@ -15689,20 +17038,72 @@ } }, "apollo-cache-control": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.14.0.tgz", - "integrity": "sha512-qN4BCq90egQrgNnTRMUHikLZZAprf3gbm8rC5Vwmc6ZdLolQ7bFsa769Hqi6Tq/lS31KLsXBLTOsRbfPHph12w==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.15.0.tgz", + "integrity": "sha512-U2uYvHZsWmR6s6CD5zlq3PepfbUAM8953CeVM2Y2QYMtJ8i4CYplEPbIWb3zTIXSPbIPeWGddM56pChI6Iz3zA==", "requires": { - "apollo-server-env": "^3.1.0", - "apollo-server-plugin-base": "^0.13.0" + "apollo-server-env": "^3.2.0", + "apollo-server-plugin-base": "^0.14.0" }, "dependencies": { + "@apollo/protobufjs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "apollo-reporting-protobuf": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", + "requires": { + "@apollo/protobufjs": "1.2.2" + } + }, + "apollo-server-env": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", + "requires": { + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" + } + }, "apollo-server-plugin-base": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz", - "integrity": "sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.14.0.tgz", + "integrity": "sha512-nTNSFuBhZURGjtWptdVqwemYUOdsvABj/GSKzeNvepiEubiv4N0rt4Gvy1inHDiMbo98wQTdF/7XohNcB9A77g==", + "requires": { + "apollo-server-types": "^0.10.0" + } + }, + "apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", "requires": { - "apollo-server-types": "^0.9.0" + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" } } } @@ -15714,22 +17115,12 @@ "requires": { "@apollo/utils.keyvaluecache": "^1.0.1", "apollo-server-env": "^4.2.1" - }, - "dependencies": { - "apollo-server-env": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", - "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", - "requires": { - "node-fetch": "^2.6.7" - } - } } }, "apollo-graphql": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.5.tgz", - "integrity": "sha512-RGt5k2JeBqrmnwRM0VOgWFiGKlGJMfmiif/4JvdaEqhMJ+xqe/9cfDYzXfn33ke2eWixsAbjEbRfy8XbaN9nTw==", + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.7.tgz", + "integrity": "sha512-bezL9ItUWUGHTm1bI/XzIgiiZbhXpsC7uxk4UxFPmcVJwJsDc3ayZ99oXxAaK+3Rbg/IoqrHckA6CwmkCsbaSA==", "requires": { "core-js-pure": "^3.10.2", "lodash.sortby": "^4.7.0", @@ -15750,35 +17141,16 @@ "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "apollo-link-http-common": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz", - "integrity": "sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==", - "dev": true, - "requires": { - "apollo-link": "^1.2.14", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" } } }, "apollo-reporting-protobuf": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", - "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.3.tgz", + "integrity": "sha512-L3+DdClhLMaRZWVmMbBcwl4Ic77CnEBPXLW53F7hkYhkaZD88ivbCVB1w/x5gunO6ZHrdzhjq0FHmTsBvPo7aQ==", "requires": { - "@apollo/protobufjs": "1.2.2" + "@apollo/protobufjs": "1.2.6" } }, "apollo-server-caching": { @@ -15790,9 +17162,9 @@ } }, "apollo-server-core": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.10.1.tgz", - "integrity": "sha512-UFFziv6h15QbKRZOA6wLyr1Sle9kns3JuQ5DEB7OYe5AIoOJNjZkWXX/tmLFUrSmlnDDryi6Sf5pDzpYmUC/UA==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.11.1.tgz", + "integrity": "sha512-t/eCKrRFK1lYZlc5pHD99iG7Np7CEm3SmbDiONA7fckR3EaB/pdsEdIkIwQ5QBBpT5JLp/nwvrZRVwhaWmaRvw==", "requires": { "@apollo/utils.keyvaluecache": "^1.0.1", "@apollo/utils.logger": "^1.0.0", @@ -15803,100 +17175,35 @@ "@graphql-tools/schema": "^8.0.0", "@josephg/resolvable": "^1.0.0", "apollo-datasource": "^3.3.2", - "apollo-reporting-protobuf": "^3.3.2", + "apollo-reporting-protobuf": "^3.3.3", "apollo-server-env": "^4.2.1", "apollo-server-errors": "^3.3.1", - "apollo-server-plugin-base": "^3.6.2", - "apollo-server-types": "^3.6.2", + "apollo-server-plugin-base": "^3.7.1", + "apollo-server-types": "^3.7.1", "async-retry": "^1.2.1", "fast-json-stable-stringify": "^2.1.0", "graphql-tag": "^2.11.0", "loglevel": "^1.6.8", "lru-cache": "^6.0.0", + "node-abort-controller": "^3.0.1", "sha.js": "^2.4.11", - "uuid": "^8.0.0", + "uuid": "^9.0.0", "whatwg-mimetype": "^3.0.0" }, "dependencies": { - "@apollo/protobufjs": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.4.tgz", - "integrity": "sha512-npVJ9NVU/pynj+SCU+fambvTneJDyCnif738DnZ7pCxdDtzeEz7WkpSIq5wNUmWm5Td55N+S2xfqZ+WP4hDLng==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - } - }, - "@apollographql/graphql-playground-html": { - "version": "1.6.29", - "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz", - "integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==", - "requires": { - "xss": "^1.0.8" - } - }, - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" - }, - "apollo-reporting-protobuf": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.2.tgz", - "integrity": "sha512-j1tx9tmkVdsLt1UPzBrvz90PdjAeKW157WxGn+aXlnnGfVjZLIRXX3x5t1NWtXvB7rVaAsLLILLtDHW382TSoQ==", - "requires": { - "@apollo/protobufjs": "1.2.4" - } - }, - "apollo-server-env": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", - "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", - "requires": { - "node-fetch": "^2.6.7" - } - }, - "apollo-server-types": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.6.2.tgz", - "integrity": "sha512-9Z54S7NB+qW1VV+kmiqwU2Q6jxWfX89HlSGCGOo3zrkrperh85LrzABgN9S92+qyeHYd72noMDg2aI039sF3dg==", - "requires": { - "@apollo/utils.keyvaluecache": "^1.0.1", - "@apollo/utils.logger": "^1.0.0", - "apollo-reporting-protobuf": "^3.3.2", - "apollo-server-env": "^4.2.1" - } - }, "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" } } }, "apollo-server-env": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.1.0.tgz", - "integrity": "sha512-iGdZgEOAuVop3vb0F2J3+kaBVi4caMoxefHosxmgzAbbSpvWehB8Y1QiSyyMeouYC38XNVk5wnZl+jdGSsWsIQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", + "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", "requires": { - "node-fetch": "^2.6.1", - "util.promisify": "^1.0.0" + "node-fetch": "^2.6.7" } }, "apollo-server-errors": { @@ -15906,9 +17213,9 @@ "requires": {} }, "apollo-server-express": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.25.3.tgz", - "integrity": "sha512-tTFYn0oKH2qqLwVj7Ez2+MiKleXACODiGh5IxsB7VuYCPMAi9Yl8iUSlwTjQUvgCWfReZjnf0vFL2k5YhDlrtQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.26.1.tgz", + "integrity": "sha512-eATTtlGhZFuo4KNRgaQ25jflUchI18oMd0vZyx0uIQ/CM0FPttO1noQ0fPAO6U0oSrxS8J9fCh8naJFDTUsZ0w==", "requires": { "@apollographql/graphql-playground-html": "1.6.27", "@types/accepts": "^1.3.5", @@ -15917,8 +17224,8 @@ "@types/express": "^4.17.12", "@types/express-serve-static-core": "^4.17.21", "accepts": "^1.3.5", - "apollo-server-core": "^2.25.3", - "apollo-server-types": "^0.9.0", + "apollo-server-core": "^2.26.1", + "apollo-server-types": "^0.10.0", "body-parser": "^1.18.3", "cors": "^2.8.5", "express": "^4.17.1", @@ -15929,38 +17236,96 @@ "type-is": "^1.6.16" }, "dependencies": { + "@apollo/protobufjs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.27", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.27.tgz", + "integrity": "sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw==", + "requires": { + "xss": "^1.0.8" + } + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "requires": { + "@types/node": "*" + } + }, "apollo-datasource": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.9.0.tgz", - "integrity": "sha512-y8H99NExU1Sk4TvcaUxTdzfq2SZo6uSj5dyh75XSQvbpH6gdAXIW9MaBcvlNC7n0cVPsidHmOcHOWxJ/pTXGjA==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.10.0.tgz", + "integrity": "sha512-wrLhuoM2MtA0KA0+3qyioe0H2FjAxjTvuFOlNCk6WberA887m0MQlWULZImCWTkKuN+zEAMerHfxN+F+W8+lBA==", "requires": { "apollo-server-caching": "^0.7.0", - "apollo-server-env": "^3.1.0" + "apollo-server-env": "^3.2.0" + } + }, + "apollo-reporting-protobuf": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", + "requires": { + "@apollo/protobufjs": "1.2.2" } }, "apollo-server-core": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.25.3.tgz", - "integrity": "sha512-Midow3uZoJ9TjFNeCNSiWElTVZlvmB7G7tG6PPoxIR9Px90/v16Q6EzunDIO0rTJHRC3+yCwZkwtf8w2AcP0sA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.26.1.tgz", + "integrity": "sha512-YnO1YXhHOnCY7Q2SZ0uUtPq6SLCw+t2uI19l59mzWuCyZYdHrtSy3zUEU6pM3tR9vvUuRGkYIfMRlo/Q8a1U5g==", "requires": { "@apollographql/apollo-tools": "^0.5.0", "@apollographql/graphql-playground-html": "1.6.27", - "@apollographql/graphql-upload-8-fork": "^8.1.3", + "@apollographql/graphql-upload-8-fork": "^8.1.4", "@josephg/resolvable": "^1.0.0", "@types/ws": "^7.0.0", - "apollo-cache-control": "^0.14.0", - "apollo-datasource": "^0.9.0", + "apollo-cache-control": "^0.15.0", + "apollo-datasource": "^0.10.0", "apollo-graphql": "^0.9.0", "apollo-reporting-protobuf": "^0.8.0", "apollo-server-caching": "^0.7.0", - "apollo-server-env": "^3.1.0", + "apollo-server-env": "^3.2.0", "apollo-server-errors": "^2.5.0", - "apollo-server-plugin-base": "^0.13.0", - "apollo-server-types": "^0.9.0", - "apollo-tracing": "^0.15.0", + "apollo-server-plugin-base": "^0.14.0", + "apollo-server-types": "^0.10.0", + "apollo-tracing": "^0.16.0", "async-retry": "^1.2.1", "fast-json-stable-stringify": "^2.0.0", - "graphql-extensions": "^0.15.0", + "graphql-extensions": "^0.16.0", "graphql-tag": "^2.11.0", "graphql-tools": "^4.0.8", "loglevel": "^1.6.7", @@ -15970,6 +17335,15 @@ "uuid": "^8.0.0" } }, + "apollo-server-env": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", + "requires": { + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" + } + }, "apollo-server-errors": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.5.0.tgz", @@ -15977,11 +17351,21 @@ "requires": {} }, "apollo-server-plugin-base": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz", - "integrity": "sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.14.0.tgz", + "integrity": "sha512-nTNSFuBhZURGjtWptdVqwemYUOdsvABj/GSKzeNvepiEubiv4N0rt4Gvy1inHDiMbo98wQTdF/7XohNcB9A77g==", + "requires": { + "apollo-server-types": "^0.10.0" + } + }, + "apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", "requires": { - "apollo-server-types": "^0.9.0" + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" } }, "uuid": { @@ -15992,17 +17376,37 @@ } }, "apollo-server-plugin-base": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.6.2.tgz", - "integrity": "sha512-erWXjLOO1u7fxQkbxJ2cwSO7p0tYzNied91I1SJ9tikXZ/2eZUyDyvrpI+4g70kOdEi+AmJ5Fo8ahEXKJ75zdg==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.7.1.tgz", + "integrity": "sha512-g3vJStmQtQvjGI289UkLMfThmOEOddpVgHLHT2bNj0sCD/bbisj4xKbBHETqaURokteqSWyyd4RDTUe0wAUDNQ==", + "requires": { + "apollo-server-types": "^3.7.1" + } + }, + "apollo-server-types": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.7.1.tgz", + "integrity": "sha512-aE9RDVplmkaOj/OduNmGa+0a1B5RIWI0o3zC1zLvBTVWMKTpo0ifVf11TyMkLCY+T7cnZqVqwyShziOyC3FyUw==", "requires": { - "apollo-server-types": "^3.6.2" + "@apollo/utils.keyvaluecache": "^1.0.1", + "@apollo/utils.logger": "^1.0.0", + "apollo-reporting-protobuf": "^3.3.3", + "apollo-server-env": "^4.2.1" + } + }, + "apollo-tracing": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.16.0.tgz", + "integrity": "sha512-Oy8kTggB+fJ/hHXwHyMpuTl5KW7u1XetKFDErZVOobUKc2zjc/NgWiC/s7SGYZCgfLodBjvwfa6rMcvLkz7c0w==", + "requires": { + "apollo-server-env": "^3.2.0", + "apollo-server-plugin-base": "^0.14.0" }, "dependencies": { "@apollo/protobufjs": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.4.tgz", - "integrity": "sha512-npVJ9NVU/pynj+SCU+fambvTneJDyCnif738DnZ7pCxdDtzeEz7WkpSIq5wNUmWm5Td55N+S2xfqZ+WP4hDLng==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -16025,75 +17429,42 @@ "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" }, "apollo-reporting-protobuf": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.3.2.tgz", - "integrity": "sha512-j1tx9tmkVdsLt1UPzBrvz90PdjAeKW157WxGn+aXlnnGfVjZLIRXX3x5t1NWtXvB7rVaAsLLILLtDHW382TSoQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", "requires": { - "@apollo/protobufjs": "1.2.4" + "@apollo/protobufjs": "1.2.2" } }, "apollo-server-env": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.2.1.tgz", - "integrity": "sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", "requires": { - "node-fetch": "^2.6.7" + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" } }, - "apollo-server-types": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.6.2.tgz", - "integrity": "sha512-9Z54S7NB+qW1VV+kmiqwU2Q6jxWfX89HlSGCGOo3zrkrperh85LrzABgN9S92+qyeHYd72noMDg2aI039sF3dg==", + "apollo-server-plugin-base": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.14.0.tgz", + "integrity": "sha512-nTNSFuBhZURGjtWptdVqwemYUOdsvABj/GSKzeNvepiEubiv4N0rt4Gvy1inHDiMbo98wQTdF/7XohNcB9A77g==", "requires": { - "@apollo/utils.keyvaluecache": "^1.0.1", - "@apollo/utils.logger": "^1.0.0", - "apollo-reporting-protobuf": "^3.3.2", - "apollo-server-env": "^4.2.1" + "apollo-server-types": "^0.10.0" } - } - } - }, - "apollo-server-types": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.9.0.tgz", - "integrity": "sha512-qk9tg4Imwpk732JJHBkhW0jzfG0nFsLqK2DY6UhvJf7jLnRePYsPxWfPiNkxni27pLE2tiNlCwoDFSeWqpZyBg==", - "requires": { - "apollo-reporting-protobuf": "^0.8.0", - "apollo-server-caching": "^0.7.0", - "apollo-server-env": "^3.1.0" - } - }, - "apollo-tracing": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.15.0.tgz", - "integrity": "sha512-UP0fztFvaZPHDhIB/J+qGuy6hWO4If069MGC98qVs0I8FICIGu4/8ykpX3X3K6RtaQ56EDAWKykCxFv4ScxMeA==", - "requires": { - "apollo-server-env": "^3.1.0", - "apollo-server-plugin-base": "^0.13.0" - }, - "dependencies": { - "apollo-server-plugin-base": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz", - "integrity": "sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg==", + }, + "apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", "requires": { - "apollo-server-types": "^0.9.0" + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" } } } }, - "apollo-upload-client": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-13.0.0.tgz", - "integrity": "sha512-lJ9/bk1BH1lD15WhWRha2J3+LrXrPIX5LP5EwiOUHv8PCORp4EUrcujrA3rI5hZeZygrTX8bshcuMdpqpSrvtA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "apollo-link": "^1.2.12", - "apollo-link-http-common": "^0.2.14", - "extract-files": "^8.0.0" - } - }, "apollo-utilities": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz", @@ -16112,38 +17483,22 @@ } } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - } - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-union": { "version": "2.1.0", @@ -16151,21 +17506,29 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, + "array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" } }, "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "optional": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true }, "asn1": { "version": "0.2.6", @@ -16175,10 +17538,27 @@ "safer-buffer": "~2.1.0" } }, + "asn1js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", + "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", + "dev": true, + "requires": { + "pvtsutils": "^1.3.2", + "pvutils": "^1.1.3", + "tslib": "^2.4.0" + } + }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true }, "ast-types": { "version": "0.13.4", @@ -16195,9 +17575,9 @@ "dev": true }, "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "async-hook-jl": { "version": "1.7.6", @@ -16214,6 +17594,13 @@ "requires": { "semver": "^5.3.0", "shimmer": "^1.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, "async-retry": { @@ -16227,12 +17614,18 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", + "dev": true }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" }, "aws4": { "version": "1.11.0", @@ -16247,81 +17640,51 @@ "follow-redirects": "^1.14.0" } }, - "babel-jest": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", - "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", - "dev": true, - "requires": { - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.4.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } + "babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", + "dev": true }, - "babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.4.0", - "babel-preset-current-node-syntax": "^1.0.0" + "babel-preset-fbjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", + "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", + "dev": true, + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" } }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" }, "balanced-match": { "version": "1.0.2", @@ -16331,7 +17694,8 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "devOptional": true }, "basic-auth": { "version": "2.0.1", @@ -16351,7 +17715,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "requires": { "tweetnacl": "^0.14.3" } @@ -16359,12 +17723,12 @@ "bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, "bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz", + "integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==", "optional": true }, "binary-extensions": { @@ -16393,28 +17757,19 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } } } } @@ -16422,7 +17777,7 @@ "blessed": { "version": "0.1.81", "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha1-+WLWh+wsNpVwrnGvhDJW5tDKESk=" + "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==" }, "bluebird": { "version": "3.5.1", @@ -16432,29 +17787,47 @@ "bodec": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", - "integrity": "sha1-vIUVVUMPI8n3ZQp172TGqUw0GMw=" + "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==" }, "body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "requires": { - "bytes": "3.1.1", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } } }, "boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, "requires": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", @@ -16470,6 +17843,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -16478,7 +17852,8 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -16499,23 +17874,16 @@ "fill-range": "^7.0.1" } }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, "bser": { @@ -16536,6 +17904,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -16544,7 +17913,7 @@ "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "buffer-from": { "version": "1.1.2", @@ -16552,47 +17921,64 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "busboy": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", - "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, "requires": { - "dicer": "0.3.0" + "streamsearch": "^1.1.0" } }, "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "c8": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz", + "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==", "dev": true, "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-reports": "^3.1.4", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9" + }, + "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "pump": "^3.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } } } }, @@ -16612,38 +17998,43 @@ "dev": true }, "camel-case": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", - "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dev": true, "requires": { - "pascal-case": "^3.1.1", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" } }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, "caniuse-lite": { - "version": "1.0.30001305", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001305.tgz", - "integrity": "sha512-p7d9YQMji8haf0f+5rbcv9WlQ+N5jMPfRAnUmZRlNxsNeBO3Yr7RYG6M2uTY1h9tCVdlkJg6YNNc4kiAiBLdWA==", + "version": "1.0.30001429", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz", + "integrity": "sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg==", "dev": true }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, "cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, "requires": { "ansicolors": "~0.3.2", "redeyed": "~2.1.0" @@ -16652,38 +18043,87 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "chance": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/chance/-/chance-1.1.8.tgz", - "integrity": "sha512-v7fi5Hj2VbR6dJEGRWLmJBA83LJMS47pkAbmROFxHWd9qmE1esHRZW8Clf1Fhzr3rjxnNZVCjOEv/ivFxeIMtg==", - "dev": true + "change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "requires": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true + "change-case-all": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.14.tgz", + "integrity": "sha512-CWVm2uT7dmSHdO/z1CXT/n47mWonyypzBbuCy5tN7uMg22BsfkhwT6oHmFCAk+gL1LOOxhdbB9SZz3J1KTY3gA==", + "dev": true, + "requires": { + "change-case": "^4.1.2", + "is-lower-case": "^2.0.2", + "is-upper-case": "^2.0.2", + "lower-case": "^2.0.2", + "lower-case-first": "^2.0.2", + "sponge-case": "^1.0.1", + "swap-case": "^2.0.2", + "title-case": "^3.0.3", + "upper-case": "^2.0.2", + "upper-case-first": "^2.0.2" + } }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true }, "charm": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", - "integrity": "sha1-BsIe7RobBq62dVPNxT4jJ0usIpY=" + "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==" + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true }, "chokidar": { "version": "3.5.3", @@ -16700,18 +18140,6 @@ "readdirp": "~3.6.0" } }, - "ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -16721,25 +18149,29 @@ "cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "requires": { "restore-cursor": "^3.1.0" } }, "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "dev": true }, "cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, "requires": { "@colors/colors": "1.5.0", "string-width": "^4.2.0" @@ -16764,40 +18196,43 @@ } } }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, "cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "devOptional": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true }, "cls-bluebird": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", - "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", + "integrity": "sha512-XVb0RPmHQyy35Tz9z34gvtUcBKUK8A/1xkGCyeFc9B0C7Zr5SysgFaswRVdwI5NEMcO+3JKlIDGIOgERSn9NdA==", "requires": { "is-bluebird": "^1.0.2", "shimmer": "^1.1.0" @@ -16811,20 +18246,15 @@ "async-hook-jl": "^1.7.6", "emitter-listener": "^1.0.1", "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, "color": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", @@ -16832,34 +18262,50 @@ "requires": { "color-convert": "^1.9.3", "color-string": "^1.6.0" + }, + "dependencies": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + } } }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true }, "colorspace": { "version": "1.1.4", @@ -16879,9 +18325,15 @@ } }, "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, + "common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true }, "compressible": { "version": "2.0.18", @@ -16895,13 +18347,41 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concurrently": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.5.0.tgz", + "integrity": "sha512-5E3mwiS+i2JYBzr5BpXkFxOnleZTMsG+WnE/dCG4/P+oiVXrbmrBwJ2ozn4SxwB2EZDrKR568X+puVohxz3/Mg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.29.1", + "lodash": "^4.17.21", + "rxjs": "^7.0.0", + "shell-quote": "^1.7.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^17.3.1" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "devOptional": true, + "optional": true, "requires": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -16911,11 +18391,16 @@ "xdg-basedir": "^4.0.0" } }, - "confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true + "constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } }, "content-disposition": { "version": "0.5.4", @@ -16940,50 +18425,82 @@ } }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "copy-paste": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/copy-paste/-/copy-paste-1.3.0.tgz", - "integrity": "sha1-p+bEocKP3t8rCB5yuX3y75X0ce0=", + "integrity": "sha512-HA6le4vPZW2EuPFixuGUpVRKPdAmZyRlF30x5lTbfX7xXHN9NwX/+Sff7Getowosoe/lZIFwrjn4hvsYGe2vRw==", "requires": { "iconv-lite": "^0.4.8", "sync-exec": "~0.6.x" } }, + "copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dev": true, + "requires": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } + } + }, "core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==" + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.0.tgz", + "integrity": "sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==" }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cors": { "version": "2.8.5", @@ -16994,14 +18511,46 @@ "vary": "^1" } }, - "cron": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", - "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", + "cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cosmiconfig-toml-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-toml-loader/-/cosmiconfig-toml-loader-1.0.0.tgz", + "integrity": "sha512-H/2gurFWVi7xXvCyvsWRLCMekl4tITJcX0QEsDMpzxtuxDyM59xLatYNg4s/k9AA/HdtCYfj2su8mgA0GSDLDA==", + "dev": true, "requires": { - "moment-timezone": "^0.5.x" + "@iarna/toml": "^2.2.5" } }, + "cosmiconfig-typescript-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.1.1.tgz", + "integrity": "sha512-9DHpa379Gp0o0Zefii35fcmuuin6q92FnLDffzdZ0l9tVd3nEobG3O+MZ06+kuBvFTSVScvNb/oHA13Nd4iipg==", + "dev": true, + "requires": {} + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "croner": { + "version": "4.1.97", + "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", + "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==" + }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -17010,6 +18559,15 @@ "cross-spawn": "^7.0.1" } }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "requires": { + "node-fetch": "2.6.7" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -17024,45 +18582,22 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "devOptional": true + "optional": true }, "cssfilter": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", - "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==" }, "culvert": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", - "integrity": "sha1-lQL18BVKLVoioCPnn3HMk2+m728=" + "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==" }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "requires": { "assert-plus": "^1.0.0" } @@ -17072,133 +18607,90 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==" }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "dependencies": { - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - } - } + "dataloader": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.1.0.tgz", + "integrity": "sha512-qTcEYLen3r7ojZNgVUaRggOI+KM7jrKxXeSHhogh/TWxYMeONEMqY+hmkobiYQozsGIyg9OYVzO4ZIfoB4I0pQ==", + "dev": true + }, + "date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "dev": true }, "dayjs": { - "version": "1.8.36", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", - "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" + }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "mimic-response": "^1.0.0" + "type-detect": "^4.0.0" } }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, "requires": { "clone": "^1.0.2" } }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "requires": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, "degenerator": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.1.tgz", - "integrity": "sha512-LFsIFEeLPlKvAKXu7j3ssIG6RT0TbI7/GhsqrI0DnHASEQjXQ0LUSYcjJteGgRGmZbl1TnMSxpNQIAiJ7Du5TQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.2.tgz", + "integrity": "sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ==", "requires": { "ast-types": "^0.13.2", "escodegen": "^1.8.1", "esprima": "^4.0.0", - "vm2": "^3.9.3" + "vm2": "^3.9.8" } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "denque": { "version": "1.5.1", @@ -17206,24 +18698,30 @@ "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true }, "deprecated-decorator": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", - "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc=" + "integrity": "sha512-MHidOOnCHGlZDKsI21+mbIIhf4Fff+hhCTB7gtVg4uoIqjcrTZc5v6M+GS2zVI0sV7PqK415rb8XaOSQsQkHOw==" }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true }, "dicer": { @@ -17232,12 +18730,19 @@ "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", "requires": { "streamsearch": "0.1.2" + }, + "dependencies": { + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==" + } } }, - "diff-sequences": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", - "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "dir-glob": { @@ -17258,28 +18763,21 @@ "esutils": "^2.0.2" } }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } + "no-case": "^3.0.4", + "tslib": "^2.0.3" } }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "devOptional": true, + "optional": true, "requires": { "is-obj": "^2.0.0" } @@ -17289,10 +18787,10 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dset": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", + "integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==", "dev": true }, "duplexify": { @@ -17307,78 +18805,10 @@ "stream-shift": "^1.0.0" } }, - "easygraphql-mock": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/easygraphql-mock/-/easygraphql-mock-0.1.17.tgz", - "integrity": "sha512-J+OLxUfV0dw5LjMlargd9iAjtur7ifgrC0djZQgDnxXLj0g5K0JQX48cY9S95Tw4MXZP24y79w5MJtJxPcDwgQ==", - "dev": true, - "requires": { - "chance": "^1.0.16", - "easygraphql-parser": "^0.0.15" - }, - "dependencies": { - "easygraphql-parser": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/easygraphql-parser/-/easygraphql-parser-0.0.15.tgz", - "integrity": "sha512-0fEXFnFlIjgyo1rxBmEsOa1wYZwIEm5Qk3qLR1bY4d7iMsPNIPKy4M6eohyQHYXww0v3RYWrHNoks0QnktJ9bw==", - "dev": true, - "requires": { - "@graphql-tools/merge": "^6.0.11" - } - } - } - }, - "easygraphql-parser": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/easygraphql-parser/-/easygraphql-parser-0.0.12.tgz", - "integrity": "sha512-lawcyfGQHY0DkDlHYCMhUOoe/O6q2gdzVLcHIXerkoAcz3ScMjLdxInO76JRuEpWc/TerPZ+HaHs18+4c79V1w==", - "dev": true, - "requires": { - "graphql": "^14.4.0", - "merge-graphql-schemas": "^1.5.8" - }, - "dependencies": { - "graphql": { - "version": "14.7.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", - "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", - "dev": true, - "requires": { - "iterall": "^1.2.2" - } - } - } - }, - "easygraphql-tester": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/easygraphql-tester/-/easygraphql-tester-5.1.6.tgz", - "integrity": "sha512-f2u8z9sgjfyZ2QGaie05oWUAYSyW2u1dq0IZImGXnD/Z20bKrJjbdI7q1Q+S51gIwP6EJGHwCTDGkPI6ClN2jQ==", - "dev": true, - "requires": { - "easygraphql-mock": "^0.1.15", - "easygraphql-parser": "^0.0.12", - "graphql": "^14.4.0", - "graphql-tools": "^4.0.4", - "lodash.isempty": "^4.4.0", - "lodash.isobject": "^3.0.2", - "merge-graphql-schemas": "^1.5.8" - }, - "dependencies": { - "graphql": { - "version": "14.7.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", - "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", - "dev": true, - "requires": { - "iterall": "^1.2.2" - } - } - } - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -17395,12 +18825,12 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.61", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.61.tgz", - "integrity": "sha512-kpzCOOFlx63C9qKRyIDEsKIUgzoe98ump7T4gU+/OLzj8gYkkWf2SIyBjhTSE0keAjMAp3i7C262YtkQOMYrGw==", + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", "dev": true }, "emitter-listener": { @@ -17411,16 +18841,11 @@ "shimmer": "^1.2.0" } }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true }, "enabled": { "version": "2.0.0", @@ -17430,13 +18855,13 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "devOptional": true, + "optional": true, "requires": { "once": "^1.4.0" } @@ -17455,41 +18880,51 @@ "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", "optional": true }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "errors": { - "version": "file:lib/helper_lib/errors" + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } }, "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.2", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" } }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -17500,22 +18935,186 @@ "is-symbol": "^1.0.2" } }, + "esbuild": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", + "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.15.13", + "@esbuild/linux-loong64": "0.15.13", + "esbuild-android-64": "0.15.13", + "esbuild-android-arm64": "0.15.13", + "esbuild-darwin-64": "0.15.13", + "esbuild-darwin-arm64": "0.15.13", + "esbuild-freebsd-64": "0.15.13", + "esbuild-freebsd-arm64": "0.15.13", + "esbuild-linux-32": "0.15.13", + "esbuild-linux-64": "0.15.13", + "esbuild-linux-arm": "0.15.13", + "esbuild-linux-arm64": "0.15.13", + "esbuild-linux-mips64le": "0.15.13", + "esbuild-linux-ppc64le": "0.15.13", + "esbuild-linux-riscv64": "0.15.13", + "esbuild-linux-s390x": "0.15.13", + "esbuild-netbsd-64": "0.15.13", + "esbuild-openbsd-64": "0.15.13", + "esbuild-sunos-64": "0.15.13", + "esbuild-windows-32": "0.15.13", + "esbuild-windows-64": "0.15.13", + "esbuild-windows-arm64": "0.15.13" + } + }, + "esbuild-android-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz", + "integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz", + "integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz", + "integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz", + "integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz", + "integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz", + "integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz", + "integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz", + "integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz", + "integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz", + "integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz", + "integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz", + "integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz", + "integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz", + "integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz", + "integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz", + "integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz", + "integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz", + "integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz", + "integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz", + "integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==", + "dev": true, + "optional": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "devOptional": true }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "4.0.0", @@ -17532,244 +19131,145 @@ "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "requires": { + "prelude-ls": "~1.1.2" + } + } } }, "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", + "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", "dev": true, "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - } - } - }, - "eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - } - }, - "eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" }, "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "ms": "^2.1.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "ms": "^2.1.1" + "is-glob": "^4.0.3" } }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", - "has": "^1.0.3", - "is-core-module": "^2.8.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { - "esutils": "^2.0.2" + "type-fest": "^0.20.2" } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, - "eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", + "eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "^4.0.1" - } + "requires": {} }, "eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -17786,45 +19286,37 @@ } }, "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true } } }, "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" } }, "esprima": { @@ -17879,94 +19371,81 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "event-target-polyfill": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/event-target-polyfill/-/event-target-polyfill-0.0.3.tgz", + "integrity": "sha512-ZMc6UuvmbinrCk4RzGyVmRyIsAyxMRlp4CqSrcQRO8Dy0A9ldbiRy5kdtBj4OtP7EClGdqGfIqo9JmOClMsGLQ==", + "dev": true }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "optional": true + "devOptional": true }, "eventemitter2": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", - "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=" + "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==" }, "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expect": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", - "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "jest-get-type": "^27.4.0", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6" - } - }, "express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.1", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.1", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.6", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } } }, "express-mongo-sanitize": { @@ -17988,6 +19467,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -17995,15 +19475,15 @@ } }, "extract-files": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-8.1.0.tgz", - "integrity": "sha512-PTGtfthZK79WUMk+avLmwx3NGdU8+iVFXC2NMGxKsn0MnihOG2lvumj+AZo8CTwTrwjXDgZ5tztbRlEdRjBonQ==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", + "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==", "dev": true }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" }, "fast-deep-equal": { "version": "3.1.3", @@ -18017,9 +19497,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -18030,9 +19510,9 @@ } }, "fast-json-patch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.0.tgz", - "integrity": "sha512-IhpytlsVTRndz0hU5t0/MGzS/etxLlfrpG5V5M9mVbuj9TrJLWaMfsox9REM5rkuGX0T+5qjpe8XA1o0gZ42nA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" }, "fast-json-stable-stringify": { "version": "2.1.0", @@ -18042,12 +19522,12 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "fast-text-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", - "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", + "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", "optional": true }, "fastq": { @@ -18068,28 +19548,50 @@ } }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "requires": { "bser": "2.1.1" } }, + "fbjs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.4.tgz", + "integrity": "sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==", + "dev": true, + "requires": { + "cross-fetch": "^3.1.5", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.30" + } + }, + "fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", + "dev": true + }, "fclone": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", - "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=" + "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==" }, "fecha": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", - "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, "requires": { "escape-string-regexp": "^1.0.5" }, @@ -18097,7 +19599,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true } } }, @@ -18135,26 +19638,42 @@ } }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "firebase-admin": { @@ -18192,9 +19711,9 @@ } }, "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "fn.name": { @@ -18203,9 +19722,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, "for-each": { "version": "0.3.3", @@ -18215,21 +19734,56 @@ "is-callable": "^1.1.3" } }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, + "form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "dev": true + }, + "formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dev": true, + "requires": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "dependencies": { + "web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "dev": true + } + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -18238,12 +19792,12 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs-capacitor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.4.tgz", - "integrity": "sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-6.2.0.tgz", + "integrity": "sha512-nKcE1UduoSKX27NSZlg879LdQc94OtbOsEmKMN2MBNudXREvijRKx2GEBsTMTfws+BrbkJoEuynbGSVRSpauvw==" }, "fs-extra": { "version": "8.1.0", @@ -18258,7 +19812,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -18269,7 +19823,7 @@ "ftp": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==", "requires": { "readable-stream": "1.1.x", "xregexp": "2.0.0" @@ -18278,12 +19832,12 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -18294,7 +19848,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" } } }, @@ -18303,11 +19857,27 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "devOptional": true + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "optional": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, "gaxios": { "version": "4.3.3", @@ -18344,28 +19914,22 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "devOptional": true }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -18375,6 +19939,12 @@ "get-intrinsic": "^1.1.1" } }, + "get-tsconfig": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.2.0.tgz", + "integrity": "sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==", + "dev": true + }, "get-uri": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", @@ -18388,25 +19958,17 @@ "ftp": "^0.3.10" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" } } }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "requires": { "assert-plus": "^1.0.0" } @@ -18414,22 +19976,22 @@ "git-node-fs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", - "integrity": "sha1-SbIV4kLr5Dqkx1Ybu6SZUhdSCA8=" + "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==" }, "git-sha1": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", - "integrity": "sha1-WZrBkrcYdYJeE6RF86bgURjC90U=" + "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==" }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -18442,43 +20004,23 @@ "is-glob": "^4.0.1" } }, - "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "requires": { - "ini": "2.0.0" - }, - "dependencies": { - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true - } - } - }, "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, "globby": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", - "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" } }, @@ -18486,46 +20028,17 @@ "version": "7.14.1", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz", "integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - } + "optional": true, + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" } }, "google-gax": { @@ -18558,62 +20071,151 @@ "node-forge": "^1.3.1" } }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "graphql": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", + "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==" + }, + "graphql-config": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-4.3.6.tgz", + "integrity": "sha512-i7mAPwc0LAZPnYu2bI8B6yXU5820Wy/ArvmOseDLZIu0OU1UTULEuexHo6ZcHXeT9NvGGaUPQZm8NV3z79YydA==", "dev": true, "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "@graphql-tools/graphql-file-loader": "^7.3.7", + "@graphql-tools/json-file-loader": "^7.3.7", + "@graphql-tools/load": "^7.5.5", + "@graphql-tools/merge": "^8.2.6", + "@graphql-tools/url-loader": "^7.9.7", + "@graphql-tools/utils": "^8.6.5", + "cosmiconfig": "7.0.1", + "cosmiconfig-toml-loader": "1.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", + "minimatch": "4.2.1", + "string-env-interpolation": "1.0.1", + "ts-node": "^10.8.1", + "tslib": "^2.4.0" }, "dependencies": { - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, "requires": { - "pump": "^3.0.0" + "brace-expansion": "^1.1.7" } } } }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - }, - "graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==" - }, "graphql-depth-limit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz", "integrity": "sha512-+3B2BaG8qQ8E18kzk9yiSdAa75i/hnnOwgSeAxVJctGQPvmeiLtqKOYF6HETCyRjiF7Xfsyal0HbLlxCQkgkrw==", "requires": { "arrify": "^1.0.1" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + } } }, "graphql-extensions": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.15.0.tgz", - "integrity": "sha512-bVddVO8YFJPwuACn+3pgmrEg6I8iBuYLuwvxiE+lcQQ7POotVZxm2rgGw0PvVYmWWf3DT7nTVDZ5ROh/ALp8mA==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.16.0.tgz", + "integrity": "sha512-rZQc/USoEIw437BGRUwoHoLPR1LA791Ltj6axONqgKIyyx2sqIO3YT9kTbB/eIUdJBrCozp4KuUeZ09xKeQDxg==", "requires": { "@apollographql/apollo-tools": "^0.5.0", - "apollo-server-env": "^3.1.0", - "apollo-server-types": "^0.9.0" + "apollo-server-env": "^3.2.0", + "apollo-server-types": "^0.10.0" + }, + "dependencies": { + "@apollo/protobufjs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz", + "integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "apollo-reporting-protobuf": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz", + "integrity": "sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==", + "requires": { + "@apollo/protobufjs": "1.2.2" + } + }, + "apollo-server-env": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.2.0.tgz", + "integrity": "sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==", + "requires": { + "node-fetch": "^2.6.1", + "util.promisify": "^1.0.0" + } + }, + "apollo-server-types": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-0.10.0.tgz", + "integrity": "sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==", + "requires": { + "apollo-reporting-protobuf": "^0.8.0", + "apollo-server-caching": "^0.7.0", + "apollo-server-env": "^3.2.0" + } + } + } + }, + "graphql-request": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-5.0.0.tgz", + "integrity": "sha512-SpVEnIo2J5k2+Zf76cUkdvIRaq5FMZvGQYnA4lUWYbc99m+fHh4CZYRRO/Ff4tCLQ613fzCm3SiDT64ubW5Gyw==", + "dev": true, + "requires": { + "@graphql-typed-document-node/core": "^3.1.1", + "cross-fetch": "^3.1.5", + "extract-files": "^9.0.0", + "form-data": "^3.0.0" + }, + "dependencies": { + "extract-files": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", + "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", + "dev": true + } } }, "graphql-subscriptions": { @@ -18656,17 +20258,43 @@ "object-path": "^0.11.5" }, "dependencies": { - "fs-capacitor": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-6.2.0.tgz", - "integrity": "sha512-nKcE1UduoSKX27NSZlg879LdQc94OtbOsEmKMN2MBNudXREvijRKx2GEBsTMTfws+BrbkJoEuynbGSVRSpauvw==" + "busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "requires": { + "dicer": "0.3.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" } } }, "graphql-ws": { - "version": "5.6.4", - "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.6.4.tgz", - "integrity": "sha512-5r8tAzznI1zeh7k12+3z07KkgXPckQbnC9h4kJ2TBDWG2wb26TJTbVHQOiAncDBgPbtXtc1A2BlttiRuPH2t/w==", + "version": "5.11.2", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.11.2.tgz", + "integrity": "sha512-4EiZ3/UXYcjm+xFGP544/yW1+DVI8ZpKASFbzrV5EDTFWJp0ZvLl4Dy2fSZAzz9imKp5pZMIcjB0x/H69Pv/6w==", + "dev": true, "requires": {} }, "gtoken": { @@ -18678,35 +20306,12 @@ "gaxios": "^4.0.0", "google-p12-pem": "^3.1.3", "jws": "^4.0.0" - }, - "dependencies": { - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - } } }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" }, "har-validator": { "version": "5.1.5", @@ -18726,19 +20331,27 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { "version": "1.0.0", @@ -18748,90 +20361,65 @@ "has-symbols": "^1.0.2" } }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, "hash-stream-validation": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", "optional": true }, + "header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "requires": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, "helmet": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz", "integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==" }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "http-parser-js": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz", - "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==" + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "devOptional": true, "requires": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -18839,35 +20427,14 @@ } }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "requires": { "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, "i18n": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.13.4.tgz", @@ -18879,21 +20446,6 @@ "messageformat": "^2.3.0", "mustache": "^4.2.0", "sprintf-js": "^1.1.2" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "iconv-lite": { @@ -18915,12 +20467,6 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, "image-hash": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/image-hash/-/image-hash-4.0.1.tgz", @@ -18932,6 +20478,12 @@ "request": "^2.81.0" } }, + "immutable": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", + "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", + "dev": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -18940,28 +20492,26 @@ "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } } }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "import-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", + "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", "dev": true }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "devOptional": true }, "indent-string": { @@ -18973,7 +20523,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -18990,9 +20540,10 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "dev": true, "requires": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -19009,17 +20560,6 @@ "strip-ansi": "^6.0.0", "through": "^2.3.6", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } } }, "internal-slot": { @@ -19032,20 +20572,40 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "is-bigint": { "version": "1.0.4", @@ -19066,7 +20626,7 @@ "is-bluebird": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", - "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" + "integrity": "sha512-PDRu1vVip5dGQg5tfn2qVCCyxbBYu5MhYUJwSfL/RoGBI97n1fxvilVazxzptZW0gcmsMH17H4EVZZI5E/RSeA==" }, "is-boolean-object": { "version": "1.1.2", @@ -19078,31 +20638,14 @@ } }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - }, - "dependencies": { - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - } - } + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" }, "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } @@ -19118,18 +20661,13 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true }, "is-glob": { "version": "4.0.3", @@ -19139,41 +20677,35 @@ "is-extglob": "^2.1.1" } }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, "is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", + "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" }, - "is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "requires": { "has-tostringtag": "^1.0.0" } @@ -19182,7 +20714,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "devOptional": true + "optional": true }, "is-path-inside": { "version": "3.0.3", @@ -19190,12 +20722,6 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -19205,10 +20731,22 @@ "has-tostringtag": "^1.0.0" } }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } }, "is-stream": { "version": "2.0.1", @@ -19240,12 +20778,31 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", + "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } }, "is-weakref": { "version": "1.0.2", @@ -19255,31 +20812,48 @@ "call-bind": "^1.0.2" } }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==" }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dev": true, + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "dev": true, + "requires": {} + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -19287,27 +20861,6 @@ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, - "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -19319,38 +20872,10 @@ "supports-color": "^7.1.0" } }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, "istanbul-reports": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", - "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -19362,533 +20887,23 @@ "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" }, - "jest": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", - "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", - "dev": true, - "requires": { - "@jest/core": "^27.4.7", - "import-local": "^3.0.2", - "jest-cli": "^27.4.7" - }, - "dependencies": { - "jest-cli": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", - "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", - "dev": true, - "requires": { - "@jest/core": "^27.4.7", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.4.7", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } - } - } - }, - "jest-changed-files": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", - "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", - "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.4.6", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-config": { - "version": "27.4.7", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", - "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", - "dev": true, - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.4.6", - "@jest/types": "^27.4.2", - "babel-jest": "^27.4.6", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-circus": "^27.4.6", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-jasmine2": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-runner": "^27.4.6", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", - "slash": "^3.0.0" - } - }, - "jest-diff": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", - "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.4.0", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - } - }, - "jest-docblock": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", - "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", - "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6" - } - }, - "jest-environment-jsdom": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", - "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", - "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "jest-mock": "^27.4.6", - "jest-util": "^27.4.2" - } - }, - "jest-get-type": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", - "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", - "dev": true - }, - "jest-haste-map": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", - "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", - "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.4.6", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "pretty-format": "^27.4.6", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", - "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", - "dev": true, - "requires": { - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - } - }, - "jest-matcher-utils": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", - "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "pretty-format": "^27.4.6" - } - }, - "jest-message-util": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", - "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.4.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "pretty-format": "^27.4.6", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" - } - } - } - }, - "jest-mock": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", - "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", - "dev": true - }, - "jest-resolve": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", - "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.4.2", - "jest-validate": "^27.4.6", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", - "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "jest-regex-util": "^27.4.0", - "jest-snapshot": "^27.4.6" - } - }, - "jest-runner": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", - "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", - "dev": true, - "requires": { - "@jest/console": "^27.4.6", - "@jest/environment": "^27.4.6", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.4.0", - "jest-environment-jsdom": "^27.4.6", - "jest-environment-node": "^27.4.6", - "jest-haste-map": "^27.4.6", - "jest-leak-detector": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-resolve": "^27.4.6", - "jest-runtime": "^27.4.6", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.6", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", - "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.4.6", - "@jest/fake-timers": "^27.4.6", - "@jest/globals": "^27.4.6", - "@jest/source-map": "^27.4.0", - "@jest/test-result": "^27.4.6", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-mock": "^27.4.6", - "jest-regex-util": "^27.4.0", - "jest-resolve": "^27.4.6", - "jest-snapshot": "^27.4.6", - "jest-util": "^27.4.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - } - } - }, - "jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", - "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.4.6", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.4.6", - "jest-get-type": "^27.4.0", - "jest-haste-map": "^27.4.6", - "jest-matcher-utils": "^27.4.6", - "jest-message-util": "^27.4.6", - "jest-util": "^27.4.2", - "natural-compare": "^1.4.0", - "pretty-format": "^27.4.6", - "semver": "^7.3.2" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", - "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", - "dev": true, - "requires": { - "@jest/types": "^27.4.2", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.4.0", - "leven": "^3.1.0", - "pretty-format": "^27.4.6" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", - "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.4.6", - "@jest/types": "^27.4.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.4.2", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", - "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "jose": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", - "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz", + "integrity": "sha512-FVoPY7SflDodE4lknJmbAHSUjLCzE2H1F6MS0RYKMQ8SR+lNccpMf8R4eqkNYyyUjR5qZReOzZo5C5YiHOCjjg==", "requires": { "@panva/asn1.js": "^1.0.0" } }, "jpeg-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", - "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" }, "js-git": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", - "integrity": "sha1-UvplWrYYd9bxB578ZTS1VPMeVEQ=", + "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==", "requires": { "bodec": "^0.1.0", "culvert": "^0.1.2", @@ -19896,6 +20911,12 @@ "pako": "^0.2.5" } }, + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -19903,129 +20924,18 @@ "dev": true }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "dev": true - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - } - } + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "jsesc": { "version": "2.5.2", @@ -20042,10 +20952,10 @@ "bignumber.js": "^9.0.0" } }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema": { @@ -20058,34 +20968,56 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha512-i/J297TW6xyj7sDFa7AmBPkQvLIxWr2kKPWI26tXydnZrzVAocNqn5DMNT1Mzk0vit1V5UkRM7C1KdVNp7Lmcg==", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "json-to-pretty-yaml": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz", + "integrity": "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==", "dev": true, "requires": { - "minimist": "^1.2.0" + "remedial": "^1.0.7", + "remove-trailing-spaces": "^1.0.6" } }, + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "requires": { "graceful-fs": "^4.1.6" } }, + "jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true + }, "jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -20103,10 +21035,29 @@ "semver": "^5.6.0" }, "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -20122,9 +21073,10 @@ } }, "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -20132,39 +21084,25 @@ } }, "jwks-rsa": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.4.tgz", - "integrity": "sha512-mpArfgPkUpX11lNtGxsF/szkasUcbWHGplZl/uFvFO2NuMHmt0dQXIihh0rkPU2yQd5niQtuUHbXnG/WKiXF6Q==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.5.tgz", + "integrity": "sha512-IODtn1SwEm7n6GQZnQLY0oxKDrMh7n/jRH1MzE8mlxWMrh2NnMyOsXTebu8vJ1qCpmuTJcL4DdiE0E4h8jnwsA==", "requires": { - "@types/express": "^4.17.13", - "@types/jsonwebtoken": "^8.5.8", + "@types/express": "^4.17.14", + "@types/jsonwebtoken": "^8.5.9", "debug": "^4.3.4", - "jose": "^2.0.5", + "jose": "^2.0.6", "limiter": "^1.1.5", "lru-memoizer": "^2.1.4" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, "requires": { - "jwa": "^1.4.1", + "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, @@ -20178,53 +21116,24 @@ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, "kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "requires": { - "package-json": "^6.3.0" - } - }, "lazy": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", - "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=" - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true + "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==" }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "limiter": { @@ -20232,22 +21141,41 @@ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "listr2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "dev": true, "requires": { - "uc.micro": "^1.0.1" + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.5", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" } }, + "local-pkg": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz", + "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", + "dev": true + }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" } }, "lodash": { @@ -20269,44 +21197,38 @@ "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" }, "lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "lodash.isempty": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", - "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", - "dev": true + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, "lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" }, "lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "lodash.isobject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", - "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", - "dev": true + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" }, "lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.lowercase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.lowercase/-/lodash.lowercase-4.3.0.tgz", + "integrity": "sha512-UcvP1IZYyDKyEL64mmrwoA1AbFu5ahojhTtkOUr1K9dbuxzS9ev8i4TxMMGCqRC9TE8uDaSoufNAXxRPNTseVA==", + "dev": true }, "lodash.merge": { "version": "4.6.2", @@ -20317,18 +21239,12 @@ "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, "log-driver": { "version": "1.2.7", @@ -20339,40 +21255,58 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, "requires": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, - "logform": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.2.tgz", - "integrity": "sha512-V6JiPThZzTsbVRspNO6TmHkR99oqYTs8fivMBYQkjZj6rxW92KxtDCPE6IkAk1DNBnYKNkjm4jYBm6JDUcyhOA==", + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, "requires": { - "colors": "1.4.0", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^1.1.0", - "triple-beam": "^1.3.0" + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } }, - "safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } } } }, - "logger": { - "version": "file:lib/helper_lib/logger", + "logform": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", + "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", "requires": { - "lodash": "^4.17.21", - "winston": "^3.3.3" + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" } }, "loglevel": { @@ -20385,6 +21319,24 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -20394,11 +21346,14 @@ "tslib": "^2.0.3" } }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "lower-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.2.tgz", + "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } }, "lru-cache": { "version": "6.0.0", @@ -20440,87 +21395,43 @@ "devOptional": true, "requires": { "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "devOptional": true - } } }, - "make-plural": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.0.0.tgz", - "integrity": "sha512-OTuzMnuhrc7G3LJU5upkhKy7EIAq/dRqANqTUh0B8au7jM5mXq9kVdla3sn3g2GCRIxgooCDQtSJ3s1fAjasbQ==" - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, - "markdown-it": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.1.tgz", - "integrity": "sha512-CzzqSSNkFRUf9vlWvhK1awpJreMRqdCrBvZ8DIoDWTOkESMIF741UPAhuAmbyWmdiFPA6WARNhnu2M6Nrhwa+A==", - "requires": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } + "make-plural": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.1.0.tgz", + "integrity": "sha512-PKkwVlAxYVo98NrbclaQIT4F5Oy+X58PZM5r2IwUSCe3syya6PXkIRCn2XCdz7p58Scgpp50PBeHmepXVDG3hg==" }, - "markdown-js": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/markdown-js/-/markdown-js-0.0.4.tgz", - "integrity": "sha512-/GDVAINnE6JXDE18JXjRXFmkE66k9rWIUOUvZPFsOlSQNQEcJEI/tiKsOMSBbTOerQV3V0/jiuVjZ3vxYO8nnQ==", - "requires": { - "markdown-it": "8.4.1", - "test": ">=0.0.5" - } + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true }, "marked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.1.tgz", - "integrity": "sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true }, "marked-terminal": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.1.1.tgz", - "integrity": "sha512-+cKTOx9P4l7HwINYhzbrBSyzgxO2HaHKGZGuB1orZsMIgXYaJyfidT81VXRdpelW/PcHEWxywscePVgI/oUF6g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-4.2.0.tgz", + "integrity": "sha512-DQfNRV9svZf0Dm9Cf5x5xaVJ1+XjxQW6XjFJ5HFkVyK52SDpj5PCBzS5X5r2w9nHr3mlB0T5201UMLue9fmhUw==", + "dev": true, "requires": { - "ansi-escapes": "^5.0.0", + "ansi-escapes": "^4.3.1", "cardinal": "^2.1.1", - "chalk": "^5.0.0", - "cli-table3": "^0.6.1", - "node-emoji": "^1.11.0", - "supports-hyperlinks": "^2.2.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", - "requires": { - "type-fest": "^1.0.2" - } - }, - "chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==" - }, - "type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" - } + "chalk": "^4.1.0", + "cli-table3": "^0.6.0", + "node-emoji": "^1.10.0", + "supports-hyperlinks": "^2.1.0" } }, "math-interval-parser": { @@ -20528,51 +21439,21 @@ "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==" }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memory-pager": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "merge-graphql-schemas": { - "version": "1.7.8", - "resolved": "https://registry.npmjs.org/merge-graphql-schemas/-/merge-graphql-schemas-1.7.8.tgz", - "integrity": "sha512-C3EJ1i86OjmbcCT524wVPRl17M5VZzgyh9kIGYAlYnAILX+7xfh8cCbMKfehh9n4opZg6CtcPogCiVZ6PB2NyQ==", - "dev": true, - "requires": { - "@graphql-toolkit/file-loading": "0.10.4", - "@graphql-toolkit/schema-merging": "0.10.4", - "tslib": "1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true - } - } + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge2": { "version": "1.4.1", @@ -20580,6 +21461,13 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "meros": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/meros/-/meros-1.2.1.tgz", + "integrity": "sha512-R2f/jxYqCAGI19KhAvaxSOxALBMkaXWH2a7rOyqQw+ZmizX5bKkEYWLzdhC+U82ZVVPVp6MCXe3EkVligh+12g==", + "dev": true, + "requires": {} + }, "messageformat": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", @@ -20613,60 +21501,56 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "optional": true }, "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" } }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "devOptional": true + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "optional": true }, "mkdirp": { "version": "1.0.4", @@ -20676,20 +21560,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" - }, - "moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" - }, - "moment-timezone": { - "version": "0.5.34", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", - "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", - "requires": { - "moment": ">= 2.9.0" - } + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, "mongodb": { "version": "3.7.3", @@ -20715,9 +21586,9 @@ } }, "mongoose": { - "version": "5.13.14", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.14.tgz", - "integrity": "sha512-j+BlQjjxgZg0iWn42kLeZTB91OejcxWpY2Z50bsZTiKJ7HHcEtcY21Godw496GMkBqJMTzmW7G/kZ04mW+Cb7Q==", + "version": "5.13.15", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.15.tgz", + "integrity": "sha512-cxp1Gbb8yUWkaEbajdhspSaKzAvsIvOtRlYD87GN/P2QEUhpd6bIvebi36T6M0tIVAMauNaK9SPA055N3PwF8Q==", "requires": { "@types/bson": "1.x || 4.0.x", "@types/mongodb": "^3.5.27", @@ -20733,13 +21604,6 @@ "safe-buffer": "5.2.1", "sift": "13.5.2", "sliced": "1.0.1" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "mongoose-legacy-pluralize": { @@ -20749,9 +21613,9 @@ "requires": {} }, "mongoose-paginate-v2": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mongoose-paginate-v2/-/mongoose-paginate-v2-1.5.0.tgz", - "integrity": "sha512-+r/M/gYfR98s1ooXoSH3aD3bMopjXKR6UpzQZSDWI22uNtoIpxia4/b80X99ho3g8AMzl0uLuQFuPL06mXHyyg==" + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mongoose-paginate-v2/-/mongoose-paginate-v2-1.7.1.tgz", + "integrity": "sha512-J8DJw3zRXcXOKoZv+RvO9tt5HotRnbo2iCR3lke+TtsQsYwQvbY3EgUkPqZXw6qCX2IByvXrW5SGNdAB0od/Cw==" }, "morgan": { "version": "1.10.0", @@ -20765,10 +21629,26 @@ "on-headers": "~1.0.2" }, "dependencies": { - "depd": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "requires": { + "ee-first": "1.1.1" + } } } }, @@ -20797,6 +21677,11 @@ "ms": "2.0.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -20805,9 +21690,9 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "mustache": { "version": "4.2.0", @@ -20820,14 +21705,20 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, "needle": { @@ -20847,18 +21738,13 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "netmask": { "version": "2.0.2", @@ -20875,15 +21761,28 @@ "tslib": "^2.0.3" } }, + "node-abort-controller": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", + "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==" + }, "node-cmd": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/node-cmd/-/node-cmd-5.0.0.tgz", - "integrity": "sha512-4sQTJmsS5uZKAPz/Df9fnIbmvOySfGdW+UreH4X5NcAOOpKjaE+K5wf4ehNBbZVPo0vQ36RkRnhhsXXJAT+Syw==" + "integrity": "sha512-4sQTJmsS5uZKAPz/Df9fnIbmvOySfGdW+UreH4X5NcAOOpKjaE+K5wf4ehNBbZVPo0vQ36RkRnhhsXXJAT+Syw==", + "dev": true + }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true }, "node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, "requires": { "lodash": "^4.17.21" } @@ -20904,103 +21803,65 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "nodemailer": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.5.tgz", - "integrity": "sha512-6VtMpwhsrixq1HDYSBBHvW0GwiWawE75dS3oal48VqRhUvKJNnKnJo2RI/bCVQubj1vgrgscMNW4DHaD6xtMCg==" + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", + "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==" }, - "nodemon": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", - "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", "dev": true, "requires": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5", - "update-notifier": "^5.1.0" + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" }, "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true } } }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, "nssocket": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", - "integrity": "sha1-Wflvb/MhVm8zxw99vu7N/cBxVPo=", + "integrity": "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==", "requires": { "eventemitter2": "~0.4.14", "lazy": "~1.0.11" @@ -21009,14 +21870,14 @@ "eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=" + "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==" } } }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", "dev": true }, "oauth-sign": { @@ -21027,7 +21888,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-hash": { "version": "3.0.0", @@ -21036,9 +21897,9 @@ "optional": true }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" }, "object-keys": { "version": "1.1.1", @@ -21051,52 +21912,31 @@ "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==" }, "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", - "dev": true, + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" } }, "object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", "requires": { + "array.prototype.reduce": "^1.0.4", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" } }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { "ee-first": "1.1.1" } @@ -21109,7 +21949,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -21126,6 +21966,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -21136,22 +21977,24 @@ "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==" }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "ora": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, "requires": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -21168,6 +22011,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -21179,36 +22023,40 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, "requires": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "aggregate-error": "^3.0.0" } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "pac-proxy-agent": { @@ -21227,55 +22075,47 @@ "socks-proxy-agent": "5" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "requires": { - "ms": "2.1.2" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "pac-resolver": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.0.tgz", - "integrity": "sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", + "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", "requires": { - "degenerator": "^3.0.1", + "degenerator": "^3.0.2", "ip": "^1.1.5", - "netmask": "^2.0.1" - } - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "netmask": "^2.0.2" } }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=" + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } }, "parent-module": { "version": "1.0.1", @@ -21286,11 +22126,28 @@ "callsites": "^3.0.0" } }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } }, "parseurl": { "version": "1.3.3", @@ -21307,16 +22164,26 @@ "tslib": "^2.0.3" } }, + "path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -21328,10 +22195,25 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "dev": true + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { "version": "4.0.0", @@ -21339,15 +22221,21 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, "peek-readable": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.0.2.tgz", - "integrity": "sha512-9fMaz6zoxw9ypO1KZy5RDJgSupEtu0Q+g/OqqsVHX3rKGR8qehRLYzsFARZ4bVvdvfknKiXvuDbkMnO1g6cRpQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "picocolors": { "version": "1.0.0", @@ -21361,83 +22249,17 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pidusage": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", - "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz", + "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==", "requires": { "safe-buffer": "^5.2.1" } }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } - } - }, "pm2": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.1.2.tgz", - "integrity": "sha512-2nJQeCWjkN0WnTkWctaoZpqrJTiUN/Icw76IMVHHzPhr/p7yQYlEQgHzlL5IFWxO2N1HdBNXNdZft2p4HUmUcA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.2.2.tgz", + "integrity": "sha512-mASxgh/MZhtVze/wijGf+tE6JKdA3lEq64FOfXVhhArkuk9Qxl4ePw9XgFJaArOXnU3bde+KbeAJHYxppVvYBQ==", "requires": { "@pm2/agent": "~2.0.0", "@pm2/io": "~5.0.0", @@ -21446,18 +22268,18 @@ "async": "~3.2.0", "blessed": "0.1.81", "chalk": "3.0.0", - "chokidar": "^3.5.1", + "chokidar": "^3.5.3", "cli-tableau": "^2.0.0", "commander": "2.15.1", - "cron": "1.8.2", - "dayjs": "~1.8.25", + "croner": "~4.1.92", + "dayjs": "~1.11.5", "debug": "^4.3.1", "enquirer": "2.3.6", "eventemitter2": "5.0.1", "fclone": "1.0.11", "mkdirp": "1.0.4", "needle": "2.4.0", - "pidusage": "2.0.21", + "pidusage": "~3.0", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.1", "pm2-deploy": "~1.0.2", @@ -21465,20 +22287,12 @@ "pm2-sysmonit": "^1.2.8", "promptly": "^2", "semver": "^7.2", - "source-map-support": "0.5.19", + "source-map-support": "0.5.21", "sprintf-js": "1.1.2", "vizion": "~2.2.1", "yamljs": "0.3.0" }, "dependencies": { - "@pm2/pm2-version-check": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", - "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", - "requires": { - "debug": "^4.3.1" - } - }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -21488,28 +22302,10 @@ "supports-color": "^7.1.0" } }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } @@ -21525,21 +22321,6 @@ "amp-message": "~0.1.1", "debug": "^4.3.1", "escape-string-regexp": "^4.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "pm2-axon-rpc": { @@ -21548,21 +22329,6 @@ "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==", "requires": { "debug": "^4.3.1" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "pm2-deploy": { @@ -21577,7 +22343,7 @@ "pm2-multimeter": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", - "integrity": "sha1-Gh5VFT1BoFU0zqI8/oYKuqDrSs4=", + "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==", "requires": { "charm": "~0.1.1" } @@ -21595,20 +22361,14 @@ "tx2": "~1.0.4" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", "optional": true, "requires": { - "ms": "2.1.2" + "safe-buffer": "^5.2.1" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true } } }, @@ -21617,21 +22377,27 @@ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + "postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "dev": true }, "prettier-linter-helpers": { @@ -21643,54 +22409,28 @@ "fast-diff": "^1.1.2" } }, - "pretty-format": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", - "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "requires": { + "asap": "~2.0.3" + } }, "promptly": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", - "integrity": "sha1-KhP6BjaIoqWYOxYf/wEIoH0m/HQ=", + "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==", "requires": { "read": "^1.0.4" } }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, "proto3-json-serializer": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.9.tgz", @@ -21745,12 +22485,19 @@ "socks-proxy-agent": "^5.0.0" }, "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "requires": { - "ms": "2.1.2" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" } }, "lru-cache": { @@ -21761,11 +22508,6 @@ "yallist": "^3.0.2" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -21784,21 +22526,15 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "devOptional": true, + "optional": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -21820,19 +22556,28 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "pvtsutils": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.2.tgz", + "integrity": "sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==", "dev": true, "requires": { - "escape-goat": "^2.0.0" + "tslib": "^2.4.0" } }, + "pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "dev": true + }, "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } }, "queue-microtask": { "version": "1.2.3", @@ -21846,46 +22591,20 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { - "bytes": "3.1.1", - "http-errors": "1.8.1", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - } - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", "requires": { "mute-stream": "~0.0.4" } @@ -21916,15 +22635,16 @@ "redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, "requires": { "esprima": "~4.0.0" } }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", "dev": true }, "regexp-clone": { @@ -21932,34 +22652,49 @@ "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "relay-runtime": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", + "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==", "dev": true, "requires": { - "rc": "^1.2.8" + "@babel/runtime": "^7.0.0", + "fbjs": "^3.0.0", + "invariant": "^2.2.4" } }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } + "remedial": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", + "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", + "dev": true }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "remove-trailing-spaces": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz", + "integrity": "sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==", "dev": true }, "request": { @@ -21989,6 +22724,16 @@ "uuid": "^3.3.2" }, "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", @@ -21996,21 +22741,6 @@ } } }, - "request-tracing": { - "version": "file:lib/helper_lib/request-tracing", - "requires": { - "cls-bluebird": "^2.1.0", - "cls-hooked": "^4.2.2", - "nanoid": "^3.1.31" - }, - "dependencies": { - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" - } - } - }, "require-at": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", @@ -22019,92 +22749,46 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "devOptional": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-in-the-middle": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", - "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz", + "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==", "requires": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "resolve": "^1.22.1" } }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -22123,23 +22807,6 @@ "requires": { "debug": "^4.1.1", "extend": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - } } }, "reusify": { @@ -22148,6 +22815,12 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -22157,10 +22830,20 @@ "glob": "^7.1.3" } }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true }, "run-parallel": { "version": "1.2.0", @@ -22177,9 +22860,10 @@ "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==" }, "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "dev": true, "requires": { "tslib": "^2.1.0" } @@ -22189,10 +22873,20 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safe-stable-stringify": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", - "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.1.tgz", + "integrity": "sha512-dVHE6bMtS/bnL2mwualjc6IxEv1F+OCUpA46pKUj6F8uDbUM0jCCulPqRNPSnWwGNKx5etqMjZYdXtrm5KJZGA==" }, "safer-buffer": { "version": "2.1.2", @@ -22213,57 +22907,57 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } + "scuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", + "integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==", + "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -22271,17 +22965,40 @@ } } }, + "sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -22309,6 +23026,12 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, + "shell-quote": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true + }, "shimmer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", @@ -22320,6 +23043,13 @@ "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", "requires": { "nanoid": "^2.1.0" + }, + "dependencies": { + "nanoid": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", + "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" + } } }, "side-channel": { @@ -22338,24 +23068,31 @@ "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" }, "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "signedsource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", + "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==", + "dev": true }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "requires": { "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } } }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -22363,9 +23100,9 @@ "dev": true }, "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -22376,20 +23113,37 @@ "sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" }, "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "dependencies": { + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + } } }, "socks-proxy-agent": { @@ -22400,21 +23154,6 @@ "agent-base": "^6.0.2", "debug": "4", "socks": "^2.3.3" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "source-map": { @@ -22422,10 +23161,16 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -22434,12 +23179,27 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "requires": { "memory-pager": "^1.0.2" } }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "dev": true + }, + "sponge-case": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.1.tgz", + "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, "sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", @@ -22464,34 +23224,17 @@ "stack-chain": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-1.3.7.tgz", - "integrity": "sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=" + "integrity": "sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==" }, "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "stream-events": { "version": "1.0.5", @@ -22509,9 +23252,10 @@ "optional": true }, "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true }, "string_decoder": { "version": "1.3.0", @@ -22521,20 +23265,17 @@ "safe-buffer": "~5.2.0" } }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } + "string-env-interpolation": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz", + "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==", + "dev": true }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -22542,56 +23283,56 @@ } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "requires": { "ansi-regex": "^5.0.1" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "strip-literal": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-0.4.2.tgz", + "integrity": "sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==", + "dev": true, + "requires": { + "acorn": "^8.8.0" + } + }, "strtok3": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.2.4.tgz", - "integrity": "sha512-GO8IcFF9GmFDvqduIspUBwCzCbqzegyVKIsSymcMgiZKeCfrN9SowtUoi8+b59WZMAjIzVZic/Ft97+pynR3Iw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", "requires": { "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.0.1" + "peek-readable": "^4.1.0" } }, "stubs": { @@ -22610,6 +23351,14 @@ "iterall": "^1.2.1", "symbol-observable": "^1.0.4", "ws": "^5.2.0 || ^6.0.0 || ^7.0.0" + }, + "dependencies": { + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} + } } }, "supports-color": { @@ -22621,9 +23370,10 @@ } }, "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -22634,70 +23384,32 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "swap-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.2.tgz", + "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, "sync-exec": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/sync-exec/-/sync-exec-0.6.2.tgz", - "integrity": "sha1-cX0izFPwzh3vVZQ2LzqJouu5EQU=", + "integrity": "sha512-FHup6L3hMWn+2asiIC/7kj/3CaMM8aAAKPx62DRk42hQkz4H2yBADR0OnnY8Eh5Bxrzb371aPUfnW4WzAUYItQ==", "optional": true }, "systeminformation": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.11.0.tgz", - "integrity": "sha512-mI/5nFK7NUe9Qbmy65WoB5TlCWKAhP4kG0w6uR2mZM8Mpdi8b45b3hTIK3W5+kQYZnYFWeS9/O5nn5rdcSvqfA==", + "version": "5.12.12", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.12.12.tgz", + "integrity": "sha512-qg9I+JxbzkgMy1eHIs+mHqVXY+LRBWLsxhffrlDm+XfzP17Jn34tLrYjrmQs3IcR6mqfXEDpfmd97FuZ32TnaQ==", "optional": true }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "talawa-request-context": { - "version": "file:lib/helper_lib/talawa-request-context", - "requires": { - "cls-bluebird": "^2.1.0", - "cls-hooked": "^4.2.2", - "i18n": "^0.13.3" - } - }, "teeny-request": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.2.0.tgz", @@ -22711,38 +23423,6 @@ "uuid": "^8.0.0" }, "dependencies": { - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, - "requires": { - "ms": "2.1.2" - } - }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -22754,25 +23434,8 @@ "term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "test": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/test/-/test-0.6.0.tgz", - "integrity": "sha1-WYasRF7Bd1QyJRLRBLoyyKY+k44=", - "requires": { - "ansi-font": "0.0.2" - } + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true }, "test-exclude": { "version": "6.0.0", @@ -22785,57 +23448,110 @@ "minimatch": "^3.0.4" } }, - "text-decoding": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz", - "integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==" - }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + "text-decoding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz", + "integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==" + }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "tinybench": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.1.tgz", + "integrity": "sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==", + "dev": true }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "tinypool": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==", "dev": true }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "tinyspy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz", + "integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "title-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, "requires": { "os-tmpdir": "~1.0.2" } }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, "to-regex-range": { @@ -22867,15 +23583,6 @@ } } }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "requires": { - "nopt": "~1.0.10" - } - }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -22888,7 +23595,13 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true }, "triple-beam": { "version": "1.3.0", @@ -22910,22 +23623,37 @@ } } }, - "tsconfig-paths": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", - "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "ts-log": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz", + "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==", + "dev": true + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" } }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "tsutils": { "version": "3.21.0", @@ -22944,10 +23672,22 @@ } } }, + "tsx": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.11.0.tgz", + "integrity": "sha512-q+q4xxu41+AafVwvAGqtNJ1ekPFd33ZhTMXvgIpHMqv/W89efwDRE9IyjhEAZm5iTHsshKaf1BYWSk789BrNCA==", + "dev": true, + "requires": { + "@esbuild-kit/cjs-loader": "^2.4.0", + "@esbuild-kit/core-utils": "^3.0.0", + "@esbuild-kit/esm-loader": "^2.5.0", + "fsevents": "~2.3.2" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "requires": { "safe-buffer": "^5.0.1" } @@ -22955,12 +23695,12 @@ "tv4": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", - "integrity": "sha1-0CDIRvrdUMhVq7JeuuzGj8EPeWM=" + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==" }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "tx2": { "version": "1.0.5", @@ -22972,11 +23712,12 @@ } }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -22986,9 +23727,9 @@ "dev": true }, "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, "type-is": { @@ -23009,39 +23750,48 @@ } }, "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, - "peer": true + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + "ua-parser-js": { + "version": "0.7.32", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", + "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", + "dev": true }, "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, - "undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true }, + "undici": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.12.0.tgz", + "integrity": "sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg==", + "dev": true, + "requires": { + "busboy": "^1.6.0" + } + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "devOptional": true, + "optional": true, "requires": { "crypto-random-string": "^2.0.0" } @@ -23054,7 +23804,7 @@ "unixify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", - "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=", + "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", "dev": true, "requires": { "normalize-path": "^2.1.1" @@ -23063,7 +23813,7 @@ "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" @@ -23074,61 +23824,40 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true }, - "update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "requires": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" } }, "uri-js": { @@ -23139,19 +23868,10 @@ "punycode": "^2.1.0" } }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "util.promisify": { "version": "1.1.1", @@ -23168,36 +23888,28 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "requires": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } + "convert-source-map": "^1.6.0" } }, "validator": { @@ -23213,18 +23925,50 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, + "vite": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.2.tgz", + "integrity": "sha512-pLrhatFFOWO9kS19bQ658CnRYzv0WLbsPih6R+iFeEEhDOuYgYCX2rztUViMz/uy/V8cLCJvLFeiOK7RJEzHcw==", + "dev": true, + "requires": { + "esbuild": "^0.15.9", + "fsevents": "~2.3.2", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + } + }, + "vitest": { + "version": "0.24.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.5.tgz", + "integrity": "sha512-zw6JhPUHtLILQDe5Q39b/SzoITkG+R7hcFjuthp4xsi6zpmfQPOZcHodZ+3bqoWl4EdGK/p1fuMiEwdxgbGLOA==", + "dev": true, + "requires": { + "@types/chai": "^4.3.3", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "chai": "^4.3.6", + "debug": "^4.3.4", + "local-pkg": "^0.4.2", + "strip-literal": "^0.4.2", + "tinybench": "^2.3.1", + "tinypool": "^0.3.0", + "tinyspy": "^1.0.2", + "vite": "^3.0.0" + } + }, "vizion": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz", @@ -23247,65 +23991,46 @@ } }, "vm2": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.9.tgz", - "integrity": "sha512-xwTm7NLh/uOjARRBs8/95H0e8fT3Ukw5D/JJWhxMbhKzNh1Nu981jQKvkep9iKYNxzlVrdzD0mlBGkDKZWprlw==", + "version": "3.9.11", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", + "integrity": "sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==", "requires": { "acorn": "^8.7.0", "acorn-walk": "^8.2.0" - }, - "dependencies": { - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" - } } }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, "requires": { - "browser-process-hrtime": "^1.0.0" + "defaults": "^1.0.3" } }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } + "web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "webcrypto-core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.5.tgz", + "integrity": "sha512-gaExY2/3EHQlRNNNVSrbG2Cg94Rutl7fAaKILS1w8ZDhGxdFOaw6EbCfHIxPy9vt/xwp5o0VQAx9aySPF6hU1A==", "dev": true, "requires": { - "makeerror": "1.0.12" - } - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "requires": { - "defaults": "^1.0.3" + "@peculiar/asn1-schema": "^2.1.6", + "@peculiar/json-schema": "^1.1.12", + "asn1js": "^3.0.1", + "pvtsutils": "^1.3.2", + "tslib": "^2.4.0" } }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "websocket-driver": { "version": "0.7.4", @@ -23322,25 +24047,21 @@ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", + "dev": true }, "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -23366,39 +24087,47 @@ "is-symbol": "^1.0.3" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, "widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, "requires": { "string-width": "^4.0.0" } }, "winston": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.5.1.tgz", - "integrity": "sha512-tbRtVy+vsSSCLcZq/8nXZaOie/S2tPXPFt4be/Q3vI/WtYwm7rrwidxVw2GRa38FIXcJ1kUM6MOZ9Jmnk3F3UA==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz", + "integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==", "requires": { + "@colors/colors": "1.5.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.3.2", + "logform": "^2.4.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.4.2" + "winston-transport": "^4.5.0" } }, "winston-transport": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.2.tgz", - "integrity": "sha512-9jmhltAr5ygt5usgUTQbEiw/7RYXpyUbEAFRCSicIacpUzPkrnQsQZSPGEI12aLK9Jth4zNcYJx3Cvznwrl8pw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", "requires": { "logform": "^2.3.2", - "readable-stream": "^3.4.0", - "triple-beam": "^1.2.0" + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" } }, "word-wrap": { @@ -23410,6 +24139,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -23419,13 +24149,13 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "devOptional": true, + "optional": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -23434,47 +24164,43 @@ } }, "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz", + "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==", + "dev": true, "requires": {} }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "devOptional": true - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "optional": true }, "xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" + "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==" }, "xss": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.10.tgz", - "integrity": "sha512-qmoqrRksmzqSKvgqzN0055UFWY7OKx1/9JWeRswwEVX9fCG5jcYRxa/A2DHcmZX6VJvjzHRQ2STeeVcQkrmLSw==", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", + "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", "requires": { "commander": "^2.20.3", "cssfilter": "0.0.10" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } } }, "xss-clean": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/xss-clean/-/xss-clean-0.1.1.tgz", - "integrity": "sha1-07poTYXM1SBUlj0BrWqzbWYtsaU=", + "integrity": "sha512-On99yydxoAEkHpraR7Wjg9cD6UmKfbtH2HXO1it2djid32osHL7Qr8bIu+dGYoOeKzf3ZszLfz1gwR/D7whZ2A==", "requires": { "xss-filters": "1.2.6" } @@ -23482,7 +24208,13 @@ "xss-filters": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/xss-filters/-/xss-filters-1.2.6.tgz", - "integrity": "sha1-aLOQicsd/4udvIiUhIObL1B/XFU=" + "integrity": "sha512-uqgwZRpVJCDfHsRX9lDrkPyCitQYzPklmLSbajJncATZKAUd1tF1x9y2VyPNFMv8SsSWed80xorSS5qGpw3WiA==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true }, "y18n": { "version": "5.0.8", @@ -23495,6 +24227,18 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true + }, "yamljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", @@ -23502,21 +24246,44 @@ "requires": { "argparse": "^1.0.7", "glob": "^7.0.5" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + } } }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "devOptional": true, + "version": "17.6.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.1.tgz", + "integrity": "sha512-leBuCGrL4dAd6ispNOGsJlhd0uZ6Qehkbu/B9KCR+Pxa/NVdNwi+i31lo0buCm6XxhJQFshXCD0/evfV4xfoUg==", + "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } } }, "yargs-parser": { @@ -23525,16 +24292,17 @@ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "devOptional": true }, - "yarn": { - "version": "1.22.17", - "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.17.tgz", - "integrity": "sha512-H0p241BXaH0UN9IeH//RT82tl5PfNraVpSpEoW+ET7lmopNC61eZ+A+IDvU8FM6Go5vx162SncDL8J1ZjRBriQ==" + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "optional": true + "devOptional": true }, "zen-observable": { "version": "0.8.15", diff --git a/package.json b/package.json index 2918ea0485..089c119a94 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,18 @@ "name": "talawa-api", "version": "1.0.0", "description": "talawa-api is a backend repository written using Node.js and graphql for generating APIs for the talawa flutter app.", - "main": "index.js", + "main": "./build/server.js", "scripts": { - "test": "jest", - "start": "cross-env pm2-runtime start index.js --watch", - "prod": "cross-env NODE_ENV=production pm2-runtime start index.js", - "test-server": "cross-env NODE_ENV=test TEST_DB=talawa-test-db nodemon index.js --ext js,graphql", - "start-test-server-in-action": "cross-env NODE_ENV=test pm2 start index.js -f", - "stop-test-server-in-action": "pm2 delete all", + "build": "tsc --pretty --project tsconfig.build.json", + "dev": "concurrently \"tsx watch ./src/server.ts\" \"graphql-codegen --watch\"", "lint": "eslint . --fix && echo 'Lint complete.'", - "setup": "npm i boxen@4.2.0 chalk@4.1.0 inquirer markdown-js marked@2.0.1 marked-terminal@5.1.1 node-cmd@5.0.0 && node setup.js", - "file-coverage": "npm test $npm_config_testfile -- --coverage --collectCoverageFrom=$npm_config_functionfile" + "postbuild": "copyfiles --error --up 1 './src/locales/*' ./build", + "prebuild": "graphql-codegen && rimraf ./build", + "prod": "cross-env NODE_ENV=production pm2-runtime start ./build/server.js", + "setup": "node ./setup/index.js", + "start": "cross-env pm2-runtime start ./build/server.js --watch", + "test": "vitest run --no-threads --coverage", + "typecheck": "graphql-codegen && tsc --noEmit --pretty" }, "repository": { "type": "git", @@ -31,68 +32,81 @@ }, "homepage": "https://github.com/PalisadoesFoundation/talawa-api#readme", "dependencies": { - "@graphql-tools/schema": "^8.3.5", - "apollo-server-core": "^3.10.1", - "apollo-server-express": "^2.25.2", - "axios": "^0.21.2", + "@graphql-tools/schema": "^8.4.0", + "apollo-server-core": "^3.11.1", + "apollo-server-express": "^2.25.4", + "axios": "^0.21.4", "bcryptjs": "^2.4.3", - "boxen": "^4.2.0", - "chalk": "^4.1.0", "cls-bluebird": "^2.1.0", "cls-hooked": "^4.2.2", "copy-paste": "^1.3.0", "cors": "^2.8.5", "cross-env": "^7.0.3", "dotenv": "^8.6.0", - "errors": "file:lib/helper_lib/errors", - "express": "^4.17.1", - "express-mongo-sanitize": "^2.0.2", - "express-rate-limit": "^5.2.6", + "express": "^4.18.1", + "express-mongo-sanitize": "^2.2.0", + "express-rate-limit": "^5.5.1", "firebase-admin": "^10.3.0", - "glob-parent": "^5.1.2", - "graphql": "^15.5.0", + "graphql": "^15.8.0", "graphql-depth-limit": "^1.1.0", "graphql-upload": "^12.0.0", - "graphql-ws": "^5.6.4", "helmet": "^4.6.0", - "i18n": "^0.13.3", + "i18n": "^0.13.4", "image-hash": "^4.0.1", - "inquirer": "^8.2.4", "jsonwebtoken": "^8.5.1", "jwt-decode": "^3.1.2", - "logger": "file:lib/helper_lib/logger", - "markdown-js": "^0.0.4", - "marked": "^2.0.1", - "marked-terminal": "^5.1.1", - "moment": "^2.29.4", - "mongoose": "^5.13.0", - "mongoose-paginate-v2": "^1.3.18", + "lodash": "^4.17.21", + "mongoose": "^5.13.14", + "mongoose-paginate-v2": "^1.7.0", "morgan": "^1.10.0", - "netmask": ">=2.0.1", - "node-cmd": "^5.0.0", - "nodemailer": "^6.7.5", - "pm2": "^5.1.2", - "request-tracing": "file:lib/helper_lib/request-tracing", + "nanoid": "^3.3.4", + "nodemailer": "^6.7.8", + "pm2": "^5.2.0", "shortid": "^2.2.16", - "talawa-request-context": "file:lib/helper_lib/talawa-request-context", "uuid": "^3.4.0", "validator": "^13.7.0", - "winston": "^3.3.3", - "ws": "^7.5.7", - "xss-clean": "^0.1.1", - "yarn": "^1.22.10" + "winston": "^3.8.0", + "xss-clean": "^0.1.1" }, "devDependencies": { - "easygraphql-tester": "^5.1.6", - "eslint": "^7.29.0", - "eslint-config-airbnb-base": "^14.2.1", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.23.4", - "eslint-plugin-jest": "^24.3.6", - "eslint-plugin-prettier": "^3.4.0", - "jest": "^27.4.7", - "netmask": ">=2.0.1", - "nodemon": "^2.0.15", - "prettier": "^2.3.2" + "@graphql-codegen/cli": "^2.6.2", + "@graphql-codegen/typescript": "^2.5.1", + "@graphql-codegen/typescript-resolvers": "^2.6.6", + "@graphql-eslint/eslint-plugin": "^3.12.0", + "@types/bcryptjs": "^2.4.2", + "@types/cls-hooked": "^4.3.3", + "@types/copy-paste": "^1.1.30", + "@types/express": "^4.17.13", + "@types/express-rate-limit": "^5.1.3", + "@types/graphql-depth-limit": "^1.1.3", + "@types/i18n": "^0.13.3", + "@types/jsonwebtoken": "^8.5.8", + "@types/lodash": "^4.14.182", + "@types/mongoose-paginate-v2": "^1.6.5", + "@types/morgan": "^1.9.3", + "@types/node": "^18.11.9", + "@types/nodemailer": "^6.4.5", + "@types/shortid": "^0.0.29", + "@types/uuid": "^3.4.10", + "@types/validator": "^13.7.3", + "@typescript-eslint/eslint-plugin": "^5.42.0", + "@typescript-eslint/parser": "^5.42.0", + "@vitest/coverage-c8": "^0.24.3", + "boxen": "^4.2.0", + "chalk": "^4.1.2", + "concurrently": "^7.5.0", + "copyfiles": "^2.4.1", + "eslint": "^8.26.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-prettier": "^4.2.1", + "inquirer": "^8.2.4", + "marked": "^2.1.3", + "marked-terminal": "^4.2.0", + "node-cmd": "^5.0.0", + "prettier": "^2.7.1", + "rimraf": "^3.0.2", + "tsx": "^3.11.0", + "typescript": "^4.8.4", + "vitest": "^0.24.3" } -} \ No newline at end of file +} diff --git a/setup/Display_About.js b/setup/Display_About.js deleted file mode 100644 index 1ca7086b2b..0000000000 --- a/setup/Display_About.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @brief Code to display information about Talawa - * @description This code reads the content from the - * `About.md` file and displays it on the console. The text - * contains basic information about the Talawa - */ - -const fs = require('fs'); -const path = require('path'); -const display_heading = require('./utils/Display_Heading'); -const display_markdown = require('./utils/Display_Markdown'); - -const display_about = () => { - //Read text from markdown file - const data = fs.readFileSync( - path.join(__dirname, 'markdown/about.md'), - 'utf-8' - ); - - //Display the text on console - display_heading('TALAWA API'); - display_markdown(data); -}; - -module.exports = display_about; diff --git a/setup/Install_Dependencies.js b/setup/Install_Dependencies.js deleted file mode 100644 index a1203cfafb..0000000000 --- a/setup/Install_Dependencies.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @brief Code to install the dependencies - * @description This code will install the dependencies - * listed in the `package.json` file. - */ -const fs = require('fs'); -const path = require('path'); -const cmd = require('node-cmd'); -const display_heading = require('./utils/Display_Heading'); -const display_markdown = require('./utils/Display_Markdown'); -const chalk = require('chalk'); - -const install_dependencies = async () => { - try { - //Display a message - display_heading('INSTALLING PROJECT DEPENDENCIES'); - const data = fs.readFileSync( - path.join(__dirname, 'markdown/Install.md'), - 'utf-8' - ); - display_markdown(data); - - //Install the dependencies - cmd.runSync('npm install -f'); - console.log(chalk.green('Project dependencies installed successfully 🎉')); - } catch (err) { - console.log(chalk.red('ERROR: Failed to install project dependencies ❌')); - console.log('REASON: ', err.message); - - process.exit(1); - } -}; - -module.exports = install_dependencies; diff --git a/setup/Start_Application.js b/setup/Start_Application.js deleted file mode 100644 index 8cc6a78aa8..0000000000 --- a/setup/Start_Application.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @brief Code to show command to start the application - * @description After all the steps of the installation havee finished, - * this code displays the command to start the application - */ -const chalk = require('chalk'); -const boxen = require('boxen'); -const display_heading = require('./utils/Display_Heading'); - -const start_application = async () => { - try { - //Display message - display_heading('START THE APPLICATION'); - console.log( - chalk.green( - 'All the installation steps have been executed successfully 🎉. \nYou can start the application using the command below' - ) - ); - - //Display the command - console.log( - boxen('npm start', { - float: 'center', - textAlignment: 'center', - borderColor: 'magenta', - borderStyle: 'bold', - padding: 1, - }) - ); - - process.exit(0); - } catch (err) { - console.log(chalk.red('ERROR: Failed to start the application')); - console.log('REASON: ', err.message); - process.exit(1); - } -}; - -module.exports = start_application; diff --git a/setup/User_Input.js b/setup/User_Input.js deleted file mode 100644 index 7f7b7094e8..0000000000 --- a/setup/User_Input.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @brief Code to provide choice for configuration - * @description This code asks the user if he/she wants to - * set up the environment variables and begins with the process - * if the user chooses so. - */ -const input = require('./utils/Input.js'); -const display_heading = require('./utils/Display_Heading'); -const set_user_configuration = require('./Set_User_Configuration'); - -const user_input = async (path) => { - try { - //Display the message - display_heading('SET USER CONFIGURATION'); - console.log( - 'Do you want to set the user configuration?\n' + - 'This will overwrite any existing environment variable(s)\n' + - 'Enter Y for yes, any other key to ignore.' - ); - - //Variable to contain the user's choice - var questions = [ - { - type: 'input', - name: 'take_user_input', - message: '->', - }, - ]; - - //Take user input - const response = await input(questions); - - //If user chooses to set the user configuration, - //then proceed with the step - if (response.take_user_input === 'Y') { - await set_user_configuration(path); - } - } catch (err) { - //console.log(chalk.red('ERROR: Failed to take user choice')); - console.log('REASON: ', err.message); - process.exit(1); - } -}; - -module.exports = user_input; diff --git a/setup/displayAbout.js b/setup/displayAbout.js new file mode 100644 index 0000000000..fd652311e6 --- /dev/null +++ b/setup/displayAbout.js @@ -0,0 +1,25 @@ +/** + * @brief Code to display information about Talawa + * @description This code reads the content from the + * `About.md` file and displays it on the console. The text + * contains basic information about the Talawa + */ + +const fs = require("fs"); +const path = require("path"); +const displayHeading = require("./utils/displayHeading"); +const displayMarkdown = require("./utils/displayMarkdown"); + +const displayAbout = () => { + //Read text from markdown file + const data = fs.readFileSync( + path.join(__dirname, "markdown/about.md"), + "utf-8" + ); + + //Display the text on console + displayHeading("TALAWA API"); + displayMarkdown(data); +}; + +module.exports = displayAbout; diff --git a/setup.js b/setup/index.js similarity index 61% rename from setup.js rename to setup/index.js index a9003dc898..402e7ef7fc 100644 --- a/setup.js +++ b/setup/index.js @@ -11,28 +11,28 @@ * Every step displays whether it has been * executed successfully or not */ -const path = require('path'); -const display_about = require('./setup/Display_About'); -const install_dependencies = require('./setup/Install_Dependencies'); -const user_input = require('./setup/User_Input'); -const start_application = require('./setup/Start_Application'); +const path = require("path"); +const displayAbout = require("./displayAbout"); +const installDependencies = require("./installDependencies"); +const userInput = require("./userInput"); +const startApplication = require("./startApplication"); /** * This asynchronous function runs the setup process * by executing each of the steps serially */ -const run_setup = async () => { +const runSetup = async () => { //1. Display information about the project - display_about(); + displayAbout(); //2. Install project dependencies - await install_dependencies(); + await installDependencies(); //3. Set up user configuration - await user_input(path.join(__dirname, '.env')); + await userInput(path.join(__dirname, ".env")); //4. Display command to start the application - await start_application(); + await startApplication(); }; -run_setup(); +runSetup(); diff --git a/setup/installDependencies.js b/setup/installDependencies.js new file mode 100644 index 0000000000..3fb4acf55a --- /dev/null +++ b/setup/installDependencies.js @@ -0,0 +1,34 @@ +/** + * @brief Code to install the dependencies + * @description This code will install the dependencies + * listed in the `package.json` file. + */ +const fs = require("fs"); +const path = require("path"); +const cmd = require("node-cmd"); +const displayHeading = require("./utils/displayHeading"); +const displayMarkdown = require("./utils/displayMarkdown"); +const chalk = require("chalk"); + +const installDependencies = async () => { + try { + //Display a message + displayHeading("INSTALLING PROJECT DEPENDENCIES"); + const data = fs.readFileSync( + path.join(__dirname, "markdown/install.md"), + "utf-8" + ); + displayMarkdown(data); + + //Install the dependencies + cmd.runSync("npm install -f"); + console.log(chalk.green("Project dependencies installed successfully 🎉")); + } catch (err) { + console.log(chalk.red("ERROR: Failed to install project dependencies ❌")); + console.log("REASON: ", err.message); + + process.exit(1); + } +}; + +module.exports = installDependencies; diff --git a/setup/markdown/Install.md b/setup/markdown/install.md similarity index 100% rename from setup/markdown/Install.md rename to setup/markdown/install.md diff --git a/setup/Set_User_Configuration.js b/setup/setUserConfiguration.js similarity index 52% rename from setup/Set_User_Configuration.js rename to setup/setUserConfiguration.js index f6697f9631..b0bc338b7f 100644 --- a/setup/Set_User_Configuration.js +++ b/setup/setUserConfiguration.js @@ -4,11 +4,11 @@ * environment variables and saves them inside a .env file. It also * checks if the MongoDB URL is valid or not */ -const fs = require('fs'); -const chalk = require('chalk'); -const display_heading = require('./utils/Display_Heading'); -const input = require('./utils/Input'); -const check_url = require('./utils/Check_Mongo_URL.js'); +const fs = require("fs"); +const chalk = require("chalk"); +const display_heading = require("./utils/displayHeading"); +const input = require("./utils/input"); +const checkMongoURL = require("./utils/checkMongoURL"); /** * @function to convert the key-value pairs of @@ -19,7 +19,7 @@ const check_url = require('./utils/Check_Mongo_URL.js'); * @returns string */ const convertObjectToString = (object) => { - let string = ''; + let string = ""; for (let key of Object.keys(object)) { string += `${key}=${object[key]}\n`; } @@ -31,32 +31,32 @@ const convertObjectToString = (object) => { * @function to take the user input and save it * inside a .env file, after verifying the URL */ -const set_user_configuration = async (path) => { +const setUserConfiguration = async (path) => { try { //Display message - display_heading('USER INPUT'); + display_heading("USER INPUT"); console.log( chalk.cyan( - 'Please fill in the required fields. All fields are compulsory.' + "Please fill in the required fields. All fields are compulsory." ) ); //Variables to store the user configuration details const questions = [ { - type: 'input', - name: 'REFRESH_TOKEN_SECRET', - message: 'REFRESH_TOKEN_SECRET', + type: "input", + name: "REFRESH_TOKEN_SECRET", + message: "REFRESH_TOKEN_SECRET", }, { - type: 'input', - name: 'ACCESS_TOKEN_SECRET', - message: 'ACCESS_TOKEN_SECRET', + type: "input", + name: "ACCESS_TOKEN_SECRET", + message: "ACCESS_TOKEN_SECRET", }, { - type: 'input', - name: 'MONGO_DB_URL', - message: 'MONGO_DB_URL', + type: "input", + name: "MONGO_DB_URL", + message: "MONGO_DB_URL", }, ]; @@ -65,29 +65,29 @@ const set_user_configuration = async (path) => { //Check if all fields have been filled if ( - !response['REFRESH_TOKEN_SECRET'] || - !response['ACCESS_TOKEN_SECRET'] || - !response['MONGO_DB_URL'] + !response["REFRESH_TOKEN_SECRET"] || + !response["ACCESS_TOKEN_SECRET"] || + !response["MONGO_DB_URL"] ) { - console.log(chalk.red('ERROR: All fields are compulsory ❌')); + console.log(chalk.red("ERROR: All fields are compulsory ❌")); process.exit(1); } //Validate the MongoDB URL - const isValidURL = await check_url(response['MONGO_DB_URL']); + const isValidURL = await checkMongoURL(response["MONGO_DB_URL"]); //If the URL is valid, then save it in .env file if (isValidURL) { const data = convertObjectToString(response); - fs.writeFileSync(path, data, { encoding: 'utf8' }); + fs.writeFileSync(path, data, { encoding: "utf8" }); } - console.log(chalk.green('User configured successfully 🎉')); + console.log(chalk.green("User configured successfully 🎉")); } catch (error) { - console.log(chalk.red('ERROR: Failed to set user configuration ❌')); - console.log('REASON: ', error.message); + console.log(chalk.red("ERROR: Failed to set user configuration ❌")); + console.log("REASON: ", error.message); process.exit(1); } }; -module.exports = set_user_configuration; +module.exports = setUserConfiguration; diff --git a/setup/Setup.md b/setup/setup.md similarity index 63% rename from setup/Setup.md rename to setup/setup.md index 7851d106c4..f2877589c6 100644 --- a/setup/Setup.md +++ b/setup/setup.md @@ -1,62 +1,65 @@ -# Setup +# setup This directory contains all the scripts required to execute the **automated installation** process of Talawa API. Each file contains a function to complete a particular step. All the functions are asynchronous and display whether the operation has been completed successfully or not. ## Structure + ``` setup -├── Display_About.js -├── Install_Dependencies.js -├── Set_User_Configuration.js -├── Start_Application.js -├── User_Input.js -├── Setup.md +├── displayAbout.js +├── installDependencies.js +├── setUserConfiguration.js +├── startApplication.js +├── userInput.js +├── setup.md ├── utils -│ ├── Check_Mongo_URL.js -│ ├── Display_Heading.js -│ ├── Display_Markdown.js -│ └── Input.js +│ ├── checkMongoURL.js +│ ├── displayHeading.js +│ ├── displayMarkdown.js +│ └── input.js └── markdown ├── About.md - └── Install.md + └── install.md ``` + Let's go through each file and understand the processes running behind the hood. +## displayAbout.js -## Display_About.js -This file displays the core features of Talawa that are present in _about_ file in the _markdown_ folder. The _display_about_ function is for reading and displaying the content. +This file displays the core features of Talawa that are present in _about_ file in the _markdown_ folder. The _displayAbout_ function is for reading and displaying the content. ![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650680373/display_about_ik4vjs.png) - -## Install_Dependencies.js +## installDependencies.js This file handles the installation of the dependencies. There are two main functions in it: - - **For displaying the message:** +- **For displaying the message:** -It reads data from the _Install_ file in the _markdown_ folder. +It reads data from the _install_ file in the _markdown_ folder. ![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720149/install1_fkrnmn.png) - - **For installing the dependencies:** - The `npm install -f` does all the work for us as shown here: - - ![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720150/install2_h62qfe.png) +- **For installing the dependencies:** + The `npm install -f` does all the work for us as shown here: + +![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720150/install2_h62qfe.png) The success/ error message is logged in a styled manner with the help of the [chalk](https://www.npmjs.com/package/chalk) package. -## Set_User_Configuration.js +## setUserConfiguration.js + This file takes user input for the required variables and saves them in a .env file after the following steps: - - Converting the user input to strings for storing in the .env file - - ![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720869/install3_e3okid.png) - - Verifying the MongoDB URL using a function written in _Check_Mongo_URL.js_ in the _utils_ folder. - - If the URL is valid, then save it in the .env file - - The following code performs the above-mentioned operations:![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650722139/user_input_bstjpv.png) +- Converting the user input to strings for storing in the .env file -## Start_Application.js +![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720869/install3_e3okid.png) + +- Verifying the MongoDB URL using a function written in _checkMongoURL.js_ in the _utils_ folder. +- If the URL is valid, then save it in the .env file + +The following code performs the above-mentioned operations:![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650722139/user_input_bstjpv.png) + +## startApplication.js Well, if you have finished all the steps of installation, the instructions in this file will take you from here! ![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720869/start_1_kgueq8.png) @@ -66,53 +69,57 @@ To start the application, run the command: `npm start` If any error occurs, the try-catch block will help us in logging it as shown: ![Image](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720869/start_2_cllene.png) -## User_Input.js -The following functions are performed with the help of this file: +## userInput.js - - **Asking for user preference if he/she wants to set up the environment variables:** - The function used for this operation is shown here: - -![https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user1_jq3e7n.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user1_jq3e7n.png) +The following functions are performed with the help of this file: +- **Asking for user preference if he/she wants to set up the environment variables:** + The function used for this operation is shown here: - - **Taking user response and setting the variables:** - After taking input from the user, it is passed to the _Set_User_Configuration.js_ file to proceed further. The _if_ block confirms whether the user wants to set up the environment variables or not. - - ![https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user_2_quas0w.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user_2_quas0w.png) +![https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user1_jq3e7n.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user1_jq3e7n.png) +- **Taking user response and setting the variables:** + After taking input from the user, it is passed to the _setUserConfiguration.js_ file to proceed further. The _if_ block confirms whether the user wants to set up the environment variables or not. +![https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user_2_quas0w.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650720877/user_2_quas0w.png) ## Utils + This sub-directory contains some utility functions needed throughout the installation process. Let's walk through each file once: -### **Check_Mongo_URL** +### **checkMongoURL** + This file checks if the MongoDB URL is valid. We use the [mongoose](https://www.npmjs.com/package/mongoose) package to connect to the database with the provided URL. If the connection gets established, it means that the URL is valid. ![https://res.cloudinary.com/dtqeozivt/image/upload/v1650726177/Screenshot_2022-04-23_203238_c2rirh.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650726177/Screenshot_2022-04-23_203238_c2rirh.png) -### **Display_Heading** +### **displayHeading** + The functions of this file display the headings for the installation process with _style_. The [boxen](https://www.npmjs.com/package/boxen) and [chalk](https://www.npmjs.com/package/chalk) packages add flavors to the CSS written by the developers. ![https://res.cloudinary.com/dtqeozivt/image/upload/v1650725600/display_heading_qjxnfj.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650725600/display_heading_qjxnfj.png) -### **Display_Markdown** +### **displayMarkdown** + The contents of a markdown file are displayed with the help of the [marked](https://www.npmjs.com/package/marked) package. ![https://res.cloudinary.com/dtqeozivt/image/upload/v1650725600/display_markdown_wxsaxg.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650725600/display_markdown_wxsaxg.png) -### **Input** +### **input** + The function takes user input in the console and returns an object containing the response of the user. [inquirer](https://www.npmjs.com/package/inquirer) package is used here. ![https://res.cloudinary.com/dtqeozivt/image/upload/v1650726037/input_ftcesy.png](https://res.cloudinary.com/dtqeozivt/image/upload/v1650726037/input_ftcesy.png) - ## markdown + This directory contains the markdown texts displayed during the installation process. #### About -The information about the Talawa project core features is in this file imported by the _Display_About_ file. -#### Install -This file contains the message to be displayed during the installation of project dependencies read by the _Install_Dependencies_ file. +The information about the Talawa project core features is in this file imported by the _displayAbout_ file. + +#### install +This file contains the message to be displayed during the installation of project dependencies read by the _installDependencies_ file. diff --git a/setup/startApplication.js b/setup/startApplication.js new file mode 100644 index 0000000000..ced2e04112 --- /dev/null +++ b/setup/startApplication.js @@ -0,0 +1,39 @@ +/** + * @brief Code to show command to start the application + * @description After all the steps of the installation havee finished, + * this code displays the command to start the application + */ +const chalk = require("chalk"); +const boxen = require("boxen"); +const displayHeading = require("./utils/displayHeading"); + +const startApplication = async () => { + try { + //Display message + displayHeading("START THE APPLICATION"); + console.log( + chalk.green( + "All the installation steps have been executed successfully 🎉. \nYou can start the application using the command below" + ) + ); + + //Display the command + console.log( + boxen("npm run dev", { + float: "center", + textAlignment: "center", + borderColor: "magenta", + borderStyle: "bold", + padding: 1, + }) + ); + + process.exit(0); + } catch (err) { + console.log(chalk.red("ERROR: Failed to start the application")); + console.log("REASON: ", err.message); + process.exit(1); + } +}; + +module.exports = startApplication; diff --git a/setup/userInput.js b/setup/userInput.js new file mode 100644 index 0000000000..b2aac144e4 --- /dev/null +++ b/setup/userInput.js @@ -0,0 +1,45 @@ +/** + * @brief Code to provide choice for configuration + * @description This code asks the user if he/she wants to + * set up the environment variables and begins with the process + * if the user chooses so. + */ +const input = require("./utils/input"); +const displayHeading = require("./utils/displayHeading"); +const setUserConfiguration = require("./setUserConfiguration"); + +const userInput = async (path) => { + try { + //Display the message + displayHeading("SET USER CONFIGURATION"); + console.log( + "Do you want to set the user configuration?\n" + + "This will overwrite any existing environment variable(s)\n" + + "Enter Y for yes, any other key to ignore." + ); + + //Variable to contain the user's choice + var questions = [ + { + type: "input", + name: "take_user_input", + message: "->", + }, + ]; + + //Take user input + const response = await input(questions); + + //If user chooses to set the user configuration, + //then proceed with the step + if (response.take_user_input === "Y") { + await setUserConfiguration(path); + } + } catch (err) { + //console.log(chalk.red('ERROR: Failed to take user choice')); + console.log("REASON: ", err.message); + process.exit(1); + } +}; + +module.exports = userInput; diff --git a/setup/utils/Display_Heading.js b/setup/utils/Display_Heading.js deleted file mode 100644 index 9173344c4d..0000000000 --- a/setup/utils/Display_Heading.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @function to take a string and display it - * inside a box. It is used to denote the individual - * installation steps. - */ -const boxen = require('boxen'); -const chalk = require('chalk'); - -const display_heading = (heading) => { - //configuration of the box to be displayed - const display_options = { - float: 'center', - padding: { left: 20, right: 20 }, - margin: 'auto', - borderStyle: 'double', - }; - - //Display the box enveloping the given heading - console.log(boxen(chalk.yellow(heading), display_options)); -}; - -module.exports = display_heading; diff --git a/setup/utils/Check_Mongo_URL.js b/setup/utils/checkMongoURL.js similarity index 57% rename from setup/utils/Check_Mongo_URL.js rename to setup/utils/checkMongoURL.js index fa8c304d12..6c2a507f59 100644 --- a/setup/utils/Check_Mongo_URL.js +++ b/setup/utils/checkMongoURL.js @@ -4,24 +4,24 @@ * valid or not and stops the installation process if invalid, * otherwise returns a Promise which resolves to true in Boolean */ -const mongoose = require('mongoose'); -const chalk = require('chalk'); +const mongoose = require("mongoose"); +const chalk = require("chalk"); -const check_url = async (mongo_db_url) => { +const checkMongoURL = async (mongodbURL) => { //Conncection configuration const options = { useNewUrlParser: true, useUnifiedTopology: true }; //Conncect to the MongoDB Server - await mongoose.connect(mongo_db_url, options).catch((err) => { + await mongoose.connect(mongodbURL, options).catch((err) => { //If connection is not established, then stop the installation process - console.log(chalk.red('ERROR: Error connecting to MongoDB server ❌')); - console.log('REASON: ', err.message); + console.log(chalk.red("ERROR: Error connecting to MongoDB server ❌")); + console.log("REASON: ", err.message); process.exit(1); }); //If connection is established, then it is successfull - console.log(chalk.green('MongoDB URL verified successfully 🎉')); + console.log(chalk.green("MongoDB URL verified successfully 🎉")); return true; }; -module.exports = check_url; +module.exports = checkMongoURL; diff --git a/setup/utils/displayHeading.js b/setup/utils/displayHeading.js new file mode 100644 index 0000000000..d56ad14674 --- /dev/null +++ b/setup/utils/displayHeading.js @@ -0,0 +1,22 @@ +/** + * @function to take a string and display it + * inside a box. It is used to denote the individual + * installation steps. + */ +const boxen = require("boxen"); +const chalk = require("chalk"); + +const displayHeading = (heading) => { + //configuration of the box to be displayed + const displayOptions = { + float: "center", + padding: { left: 20, right: 20 }, + margin: "auto", + borderStyle: "double", + }; + + //Display the box enveloping the given heading + console.log(boxen(chalk.yellow(heading), displayOptions)); +}; + +module.exports = displayHeading; diff --git a/setup/utils/Display_Markdown.js b/setup/utils/displayMarkdown.js similarity index 50% rename from setup/utils/Display_Markdown.js rename to setup/utils/displayMarkdown.js index 045550d784..60471f173e 100644 --- a/setup/utils/Display_Markdown.js +++ b/setup/utils/displayMarkdown.js @@ -1,15 +1,15 @@ /** * @function to display the content of a markdown file */ -var marked = require('marked'); -var TerminalRenderer = require('marked-terminal'); +var marked = require("marked"); +var TerminalRenderer = require("marked-terminal"); marked.setOptions({ renderer: new TerminalRenderer(), }); -const display_markdown = (text) => { +const displayMarkdown = (text) => { console.log(marked(text)); }; -module.exports = display_markdown; +module.exports = displayMarkdown; diff --git a/setup/utils/Input.js b/setup/utils/input.js similarity index 89% rename from setup/utils/Input.js rename to setup/utils/input.js index e178c8382e..b4363e57de 100644 --- a/setup/utils/Input.js +++ b/setup/utils/input.js @@ -3,7 +3,7 @@ * @parameters questions: Array of JavaScript objects containing variables and questions * @returns An object of the responses of the user */ -const inquirer = require('inquirer'); +const inquirer = require("inquirer"); const input = async (questions) => { const answer = await inquirer.prompt(questions); diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000000..92e36711a6 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,93 @@ +export const CHAT_NOT_FOUND = "Chat not found"; +export const CHAT_NOT_FOUND_CODE = "chat.notFound"; +export const CHAT_NOT_FOUND_MESSAGE = "chat.notFound"; +export const CHAT_NOT_FOUND_PARAM = "chat"; + +export const COMMENT_NOT_FOUND = "Comment not found"; +export const COMMENT_NOT_FOUND_CODE = "comment.notFound"; +export const COMMENT_NOT_FOUND_MESSAGE = "comment.notFound"; +export const COMMENT_NOT_FOUND_PARAM = "comment"; + +export const ERROR_IN_SENDING_MAIL = "Error in sending mail"; + +export const EVENT_NOT_FOUND = "Event not found"; +export const EVENT_NOT_FOUND_CODE = "event.notFound"; +export const EVENT_NOT_FOUND_MESSAGE = "event.notFound"; +export const EVENT_NOT_FOUND_PARAM = "event"; + +export const EVENT_PROJECT_NOT_FOUND = "EventProject not found"; +export const EVENT_PROJECT_NOT_FOUND_CODE = "eventProject.notFound"; +export const EVENT_PROJECT_NOT_FOUND_MESSAGE = "eventProject.notFound"; +export const EVENT_PROJECT_NOT_FOUND_PARAM = "eventProject"; + +export const INVALID_OTP = "Invalid OTP"; + +export const IN_PRODUCTION = process.env.NODE_ENV === "production"; + +export const MEMBER_NOT_FOUND = "Member not found"; +export const MEMBER_NOT_FOUND_CODE = "member.notFound"; +export const MEMBER_NOT_FOUND_MESSAGE = "member.notFound"; +export const MEMBER_NOT_FOUND_PARAM = "member"; + +export const MEMBERSHIP_REQUEST_NOT_FOUND = "Membership Request not found"; +export const MEMBERSHIP_REQUEST_NOT_FOUND_CODE = "membershipRequest.notFound"; +export const MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE = + "membershipRequest.notFound"; +export const MEMBERSHIP_REQUEST_NOT_FOUND_PARAM = "membershipRequest"; + +export const ORGANIZATION_MEMBER_NOT_FOUND = + "Organization's user is not a member"; +export const ORGANIZATION_MEMBER_NOT_FOUND_CODE = + "organization.member.notFound"; +export const ORGANIZATION_MEMBER_NOT_FOUND_MESSAGE = + "organization.member.notFound"; +export const ORGANIZATION_MEMBER_NOT_FOUND_PARAM = "organizationMember"; + +export const ORGANIZATION_NOT_AUTHORIZED = "Organization is not authorized"; +export const ORGANIZATION_NOT_AUTHORIZED_CODE = "org.notAuthorized"; +export const ORGANIZATION_NOT_AUTHORIZED_MESSAGE = "org.notAuthorized"; +export const ORGANIZATION_NOT_AUTHORIZED_PARAM = "org"; + +export const ORGANIZATION_NOT_FOUND = "Organization not found"; +export const ORGANIZATION_NOT_FOUND_CODE = "organization.notFound"; +export const ORGANIZATION_NOT_FOUND_MESSAGE = "organization.notFound"; +export const ORGANIZATION_NOT_FOUND_PARAM = "organization"; + +export const POST_NOT_FOUND = "Post not found"; +export const POST_NOT_FOUND_CODE = "post.notFound"; +export const POST_NOT_FOUND_MESSAGE = "post.notFound"; +export const POST_NOT_FOUND_PARAM = "post"; + +export const REGISTRANT_ALREADY_EXIST = "Already registered for the event"; +export const REGISTRANT_ALREADY_EXIST_CODE = "registrant.alreadyExist"; +export const REGISTRANT_ALREADY_EXIST_MESSAGE = "registrant.alreadyExist"; +export const REGISTRANT_ALREADY_EXIST_PARAM = "registrant"; + +export const STATUS_ACTIVE = "ACTIVE"; + +export const URL = + process.env.NODE_ENV === "test" + ? "http://localhost:4000/graphql" + : "http://calico.palisadoes.org/talawa/graphql"; + +export const USER_ALREADY_MEMBER = "User is already a member"; +export const USER_ALREADY_MEMBER_CODE = "user.alreadyMember"; +export const USER_ALREADY_MEMBER_MESSAGE = "user.alreadyMember"; +export const USER_ALREADY_MEMBER_PARAM = "user"; + +export const USER_ALREADY_UNREGISTERED = "Already registered for the event"; +export const USER_ALREADY_UNREGISTERED_CODE = "registrant.alreadyUnregistered"; +export const USER_ALREADY_UNREGISTERED_MESSAGE = + "registrant.alreadyUnregistered"; +export const USER_ALREADY_UNREGISTERED_PARAM = "registrant"; + +export const USER_NOT_AUTHORIZED = + "User is not authorized for performing this operation"; +export const USER_NOT_AUTHORIZED_CODE = "user.notAuthorized"; +export const USER_NOT_AUTHORIZED_MESSAGE = "user.notAuthorized"; +export const USER_NOT_AUTHORIZED_PARAM = "user"; + +export const USER_NOT_FOUND = "User not found"; +export const USER_NOT_FOUND_CODE = "user.notFound"; +export const USER_NOT_FOUND_MESSAGE = "user.notFound"; +export const USER_NOT_FOUND_PARAM = "user"; diff --git a/src/db.ts b/src/db.ts new file mode 100644 index 0000000000..9dbf803a82 --- /dev/null +++ b/src/db.ts @@ -0,0 +1,20 @@ +import mongoose from "mongoose"; +import { logger } from "./lib/libraries"; + +export const connect = async () => { + try { + await mongoose.connect(process.env.MONGO_DB_URL!, { + useCreateIndex: true, + useUnifiedTopology: true, + useFindAndModify: false, + useNewUrlParser: true, + }); + } catch (error) { + logger.error("Error while connecting to mongo database", error); + process.exit(1); + } +}; + +export const disconnect = async () => { + await mongoose.connection.close(); +}; diff --git a/src/generated/graphqlCodegen.ts b/src/generated/graphqlCodegen.ts new file mode 100644 index 0000000000..1b1e4883c5 --- /dev/null +++ b/src/generated/graphqlCodegen.ts @@ -0,0 +1,2124 @@ +import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql'; +import { Interface_MessageChat } from '../lib/models/MessageChat'; +import { Interface_Comment } from '../lib/models/Comment'; +import { Interface_DirectChat } from '../lib/models/DirectChat'; +import { Interface_DirectChatMessage } from '../lib/models/DirectChatMessage'; +import { Interface_Donation } from '../lib/models/Donation'; +import { Interface_Event } from '../lib/models/Event'; +import { Interface_Group } from '../lib/models/Group'; +import { Interface_GroupChat } from '../lib/models/GroupChat'; +import { Interface_GroupChatMessage } from '../lib/models/GroupChatMessage'; +import { Interface_Language } from '../lib/models/Language'; +import { Interface_MembershipRequest } from '../lib/models/MembershipRequest'; +import { Interface_Message } from '../lib/models/Message'; +import { Interface_Organization } from '../lib/models/Organization'; +import { Interface_Plugin } from '../lib/models/Plugin'; +import { Interface_PluginField } from '../lib/models/PluginField'; +import { Interface_Post } from '../lib/models/Post'; +import { Interface_Task } from '../lib/models/Task'; +import { Interface_User } from '../lib/models/User'; +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type Omit = Pick>; +export type RequireFields = Omit & { [P in K]-?: NonNullable }; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: string; + String: string; + Boolean: boolean; + Int: number; + Float: number; + Upload: any; +}; + +export type AggregatePost = { + __typename?: 'AggregatePost'; + count: Scalars['Int']; +}; + +export type AggregateUser = { + __typename?: 'AggregateUser'; + count: Scalars['Int']; +}; + +export type AndroidFirebaseOptions = { + __typename?: 'AndroidFirebaseOptions'; + apiKey?: Maybe; + appId?: Maybe; + messagingSenderId?: Maybe; + projectId?: Maybe; + storageBucket?: Maybe; +}; + +export type AuthData = { + __typename?: 'AuthData'; + accessToken: Scalars['String']; + androidFirebaseOptions: AndroidFirebaseOptions; + iosFirebaseOptions: IosFirebaseOptions; + refreshToken: Scalars['String']; + user: User; +}; + +export type Comment = { + __typename?: 'Comment'; + _id?: Maybe; + createdAt?: Maybe; + creator: User; + likeCount?: Maybe; + likedBy?: Maybe>>; + post: Post; + text: Scalars['String']; +}; + +export type CommentInput = { + text: Scalars['String']; +}; + +export type DeletePayload = { + __typename?: 'DeletePayload'; + success: Scalars['Boolean']; +}; + +export type DirectChat = { + __typename?: 'DirectChat'; + _id: Scalars['ID']; + creator: User; + messages?: Maybe>>; + organization: Organization; + users: Array; +}; + +export type DirectChatMessage = { + __typename?: 'DirectChatMessage'; + _id: Scalars['ID']; + createdAt: Scalars['String']; + directChatMessageBelongsTo: DirectChat; + messageContent: Scalars['String']; + receiver: User; + sender: User; +}; + +export type Donation = { + __typename?: 'Donation'; + _id: Scalars['ID']; + amount: Scalars['Float']; + nameOfOrg: Scalars['String']; + nameOfUser: Scalars['String']; + orgId: Scalars['ID']; + payPalId: Scalars['String']; + userId: Scalars['ID']; +}; + +export type Event = { + __typename?: 'Event'; + _id: Scalars['ID']; + admins?: Maybe>>; + allDay: Scalars['Boolean']; + creator: User; + description: Scalars['String']; + endDate: Scalars['String']; + endTime?: Maybe; + isPublic: Scalars['Boolean']; + isRegisterable: Scalars['Boolean']; + latitude?: Maybe; + location?: Maybe; + longitude?: Maybe; + organization?: Maybe; + recurrance?: Maybe; + recurring: Scalars['Boolean']; + registrants?: Maybe>>; + startDate: Scalars['String']; + startTime?: Maybe; + status: Status; + tasks?: Maybe>>; + title: Scalars['String']; +}; + + +export type EventAdminsArgs = { + adminId?: InputMaybe; +}; + +export type EventInput = { + allDay: Scalars['Boolean']; + description: Scalars['String']; + endDate?: InputMaybe; + endTime?: InputMaybe; + isPublic: Scalars['Boolean']; + isRegisterable: Scalars['Boolean']; + latitude?: InputMaybe; + location?: InputMaybe; + longitude?: InputMaybe; + organizationId: Scalars['ID']; + recurrance?: InputMaybe; + recurring: Scalars['Boolean']; + startDate: Scalars['String']; + startTime?: InputMaybe; + title: Scalars['String']; +}; + +export enum EventOrderByInput { + AllDayAsc = 'allDay_ASC', + AllDayDesc = 'allDay_DESC', + DescriptionAsc = 'description_ASC', + DescriptionDesc = 'description_DESC', + EndDateAsc = 'endDate_ASC', + EndDateDesc = 'endDate_DESC', + EndTimeAsc = 'endTime_ASC', + EndTimeDesc = 'endTime_DESC', + IdAsc = 'id_ASC', + IdDesc = 'id_DESC', + LocationAsc = 'location_ASC', + LocationDesc = 'location_DESC', + RecurranceAsc = 'recurrance_ASC', + RecurranceDesc = 'recurrance_DESC', + StartDateAsc = 'startDate_ASC', + StartDateDesc = 'startDate_DESC', + StartTimeAsc = 'startTime_ASC', + StartTimeDesc = 'startTime_DESC', + TitleAsc = 'title_ASC', + TitleDesc = 'title_DESC' +} + +export type EventRegistrants = { + __typename?: 'EventRegistrants'; + event: Event; + isRegistered: Scalars['Boolean']; +}; + +export type ExtendSession = { + __typename?: 'ExtendSession'; + accessToken: Scalars['String']; + refreshToken: Scalars['String']; +}; + +export type ForgotPasswordData = { + newPassword: Scalars['String']; + otpToken: Scalars['String']; + userOtp: Scalars['String']; +}; + +export type Group = { + __typename?: 'Group'; + _id?: Maybe; + admins?: Maybe>>; + createdAt?: Maybe; + description?: Maybe; + organization: Organization; + title?: Maybe; +}; + +export type GroupChat = { + __typename?: 'GroupChat'; + _id: Scalars['ID']; + creator: User; + messages?: Maybe>>; + organization: Organization; + users: Array; +}; + +export type GroupChatMessage = { + __typename?: 'GroupChatMessage'; + _id: Scalars['ID']; + createdAt: Scalars['String']; + groupChatMessageBelongsTo: GroupChat; + messageContent: Scalars['String']; + sender: User; +}; + +export type GroupInput = { + description?: InputMaybe; + organizationId: Scalars['ID']; + title?: InputMaybe; +}; + +export type IosFirebaseOptions = { + __typename?: 'IOSFirebaseOptions'; + apiKey?: Maybe; + appId?: Maybe; + iosBundleId?: Maybe; + iosClientId?: Maybe; + messagingSenderId?: Maybe; + projectId?: Maybe; + storageBucket?: Maybe; +}; + +export type Language = { + __typename?: 'Language'; + _id: Scalars['ID']; + createdAt: Scalars['String']; + en: Scalars['String']; + translation?: Maybe>>; +}; + +export type LanguageInput = { + en_value: Scalars['String']; + translation_lang_code: Scalars['String']; + translation_value: Scalars['String']; +}; + +export type LanguageModel = { + __typename?: 'LanguageModel'; + _id: Scalars['ID']; + createdAt: Scalars['String']; + lang_code: Scalars['String']; + value: Scalars['String']; + verified: Scalars['Boolean']; +}; + +export type LoginInput = { + email: Scalars['String']; + password: Scalars['String']; +}; + +export type MembershipRequest = { + __typename?: 'MembershipRequest'; + _id: Scalars['ID']; + organization: Organization; + user: User; +}; + +export type Message = { + __typename?: 'Message'; + _id: Scalars['ID']; + createdAt?: Maybe; + creator?: Maybe; + imageUrl?: Maybe; + text?: Maybe; + videoUrl?: Maybe; +}; + +export type MessageChat = { + __typename?: 'MessageChat'; + _id: Scalars['ID']; + createdAt: Scalars['String']; + languageBarrier?: Maybe; + message: Scalars['String']; + receiver: User; + sender: User; +}; + +export type MessageChatInput = { + message: Scalars['String']; + receiver: Scalars['ID']; +}; + +export type MultipleUsersAndOrganizationInput = { + organizationId: Scalars['ID']; + userIds: Array; +}; + +export type Mutation = { + __typename?: 'Mutation'; + acceptAdmin: Scalars['Boolean']; + acceptMembershipRequest: MembershipRequest; + addLanguageTranslation: Language; + addOrganizationImage: Organization; + addUserImage: User; + addUserToGroupChat: GroupChat; + adminRemoveEvent: Event; + adminRemoveGroup: Message; + adminRemovePost: Post; + blockPluginCreationBySuperadmin: User; + blockUser: User; + cancelMembershipRequest: MembershipRequest; + createAdmin: User; + createComment?: Maybe; + createDirectChat: DirectChat; + createDonation: Donation; + createEvent: Event; + createGroup: Group; + createGroupChat: GroupChat; + createMessageChat: MessageChat; + createOrganization: Organization; + createPlugin: Plugin; + createPost?: Maybe; + createTask: Task; + deleteDonationById: DeletePayload; + forgotPassword: Scalars['Boolean']; + joinPublicOrganization: User; + leaveOrganization: User; + likeComment?: Maybe; + likePost?: Maybe; + login: AuthData; + logout: Scalars['Boolean']; + otp: OtpData; + recaptcha: Scalars['Boolean']; + refreshToken: ExtendSession; + registerForEvent: Event; + rejectAdmin: Scalars['Boolean']; + rejectMembershipRequest: MembershipRequest; + removeAdmin: User; + removeComment?: Maybe; + removeDirectChat: DirectChat; + removeEvent: Event; + removeGroupChat: GroupChat; + removeMember: Organization; + removeOrganization: User; + removeOrganizationImage: Organization; + removePost?: Maybe; + removeTask?: Maybe; + removeUserFromGroupChat: GroupChat; + removeUserImage: User; + revokeRefreshTokenForUser: Scalars['Boolean']; + saveFcmToken: Scalars['Boolean']; + sendMembershipRequest: MembershipRequest; + sendMessageToDirectChat: DirectChatMessage; + sendMessageToGroupChat: GroupChatMessage; + signUp: AuthData; + unblockUser: User; + unlikeComment?: Maybe; + unlikePost?: Maybe; + unregisterForEventByUser: Event; + updateEvent: Event; + updateLanguage: User; + updateOrganization: Organization; + updatePluginInstalledOrgs: Plugin; + updatePluginStatus: Plugin; + updateTask?: Maybe; + updateUserProfile: User; + updateUserType: Scalars['Boolean']; +}; + + +export type MutationAcceptAdminArgs = { + id: Scalars['ID']; +}; + + +export type MutationAcceptMembershipRequestArgs = { + membershipRequestId: Scalars['ID']; +}; + + +export type MutationAddLanguageTranslationArgs = { + data: LanguageInput; +}; + + +export type MutationAddOrganizationImageArgs = { + file: Scalars['Upload']; + organizationId: Scalars['String']; +}; + + +export type MutationAddUserImageArgs = { + file: Scalars['Upload']; +}; + + +export type MutationAddUserToGroupChatArgs = { + chatId: Scalars['ID']; + userId: Scalars['ID']; +}; + + +export type MutationAdminRemoveEventArgs = { + eventId: Scalars['ID']; +}; + + +export type MutationAdminRemoveGroupArgs = { + groupId: Scalars['ID']; +}; + + +export type MutationAdminRemovePostArgs = { + organizationId: Scalars['ID']; + postId: Scalars['ID']; +}; + + +export type MutationBlockPluginCreationBySuperadminArgs = { + blockUser: Scalars['Boolean']; + userId: Scalars['ID']; +}; + + +export type MutationBlockUserArgs = { + organizationId: Scalars['ID']; + userId: Scalars['ID']; +}; + + +export type MutationCancelMembershipRequestArgs = { + membershipRequestId: Scalars['ID']; +}; + + +export type MutationCreateAdminArgs = { + data: UserAndOrganizationInput; +}; + + +export type MutationCreateCommentArgs = { + data: CommentInput; + postId: Scalars['ID']; +}; + + +export type MutationCreateDirectChatArgs = { + data?: InputMaybe; +}; + + +export type MutationCreateDonationArgs = { + amount: Scalars['Float']; + nameOfOrg: Scalars['String']; + nameOfUser: Scalars['String']; + orgId: Scalars['ID']; + payPalId: Scalars['ID']; + userId: Scalars['ID']; +}; + + +export type MutationCreateEventArgs = { + data?: InputMaybe; +}; + + +export type MutationCreateGroupArgs = { + data: GroupInput; +}; + + +export type MutationCreateGroupChatArgs = { + data?: InputMaybe; +}; + + +export type MutationCreateMessageChatArgs = { + data: MessageChatInput; +}; + + +export type MutationCreateOrganizationArgs = { + data?: InputMaybe; + file?: InputMaybe; +}; + + +export type MutationCreatePluginArgs = { + installedOrgs?: InputMaybe>; + pluginCreatedBy: Scalars['String']; + pluginDesc: Scalars['String']; + pluginInstallStatus: Scalars['Boolean']; + pluginName: Scalars['String']; +}; + + +export type MutationCreatePostArgs = { + data: PostInput; + file?: InputMaybe; +}; + + +export type MutationCreateTaskArgs = { + data?: InputMaybe; + eventId: Scalars['ID']; +}; + + +export type MutationDeleteDonationByIdArgs = { + id: Scalars['ID']; +}; + + +export type MutationForgotPasswordArgs = { + data: ForgotPasswordData; +}; + + +export type MutationJoinPublicOrganizationArgs = { + organizationId: Scalars['ID']; +}; + + +export type MutationLeaveOrganizationArgs = { + organizationId: Scalars['ID']; +}; + + +export type MutationLikeCommentArgs = { + id: Scalars['ID']; +}; + + +export type MutationLikePostArgs = { + id: Scalars['ID']; +}; + + +export type MutationLoginArgs = { + data: LoginInput; +}; + + +export type MutationOtpArgs = { + data: OtpInput; +}; + + +export type MutationRecaptchaArgs = { + data: RecaptchaVerification; +}; + + +export type MutationRefreshTokenArgs = { + refreshToken: Scalars['String']; +}; + + +export type MutationRegisterForEventArgs = { + id: Scalars['ID']; +}; + + +export type MutationRejectAdminArgs = { + id: Scalars['ID']; +}; + + +export type MutationRejectMembershipRequestArgs = { + membershipRequestId: Scalars['ID']; +}; + + +export type MutationRemoveAdminArgs = { + data: UserAndOrganizationInput; +}; + + +export type MutationRemoveCommentArgs = { + id: Scalars['ID']; +}; + + +export type MutationRemoveDirectChatArgs = { + chatId: Scalars['ID']; + organizationId: Scalars['ID']; +}; + + +export type MutationRemoveEventArgs = { + id: Scalars['ID']; +}; + + +export type MutationRemoveGroupChatArgs = { + chatId: Scalars['ID']; +}; + + +export type MutationRemoveMemberArgs = { + data: MultipleUsersAndOrganizationInput; +}; + + +export type MutationRemoveOrganizationArgs = { + id: Scalars['ID']; +}; + + +export type MutationRemoveOrganizationImageArgs = { + organizationId: Scalars['String']; +}; + + +export type MutationRemovePostArgs = { + id: Scalars['ID']; +}; + + +export type MutationRemoveTaskArgs = { + id: Scalars['ID']; +}; + + +export type MutationRemoveUserFromGroupChatArgs = { + chatId: Scalars['ID']; + userId: Scalars['ID']; +}; + + +export type MutationRevokeRefreshTokenForUserArgs = { + userId: Scalars['String']; +}; + + +export type MutationSaveFcmTokenArgs = { + token?: InputMaybe; +}; + + +export type MutationSendMembershipRequestArgs = { + organizationId: Scalars['ID']; +}; + + +export type MutationSendMessageToDirectChatArgs = { + chatId: Scalars['ID']; + messageContent: Scalars['String']; +}; + + +export type MutationSendMessageToGroupChatArgs = { + chatId: Scalars['ID']; + messageContent: Scalars['String']; +}; + + +export type MutationSignUpArgs = { + data: UserInput; + file?: InputMaybe; +}; + + +export type MutationUnblockUserArgs = { + organizationId: Scalars['ID']; + userId: Scalars['ID']; +}; + + +export type MutationUnlikeCommentArgs = { + id: Scalars['ID']; +}; + + +export type MutationUnlikePostArgs = { + id: Scalars['ID']; +}; + + +export type MutationUnregisterForEventByUserArgs = { + id: Scalars['ID']; +}; + + +export type MutationUpdateEventArgs = { + data?: InputMaybe; + id: Scalars['ID']; +}; + + +export type MutationUpdateLanguageArgs = { + languageCode: Scalars['String']; +}; + + +export type MutationUpdateOrganizationArgs = { + data?: InputMaybe; + id: Scalars['ID']; +}; + + +export type MutationUpdatePluginInstalledOrgsArgs = { + id: Scalars['ID']; + orgId: Scalars['ID']; +}; + + +export type MutationUpdatePluginStatusArgs = { + id: Scalars['ID']; + status: Scalars['Boolean']; +}; + + +export type MutationUpdateTaskArgs = { + data?: InputMaybe; + id: Scalars['ID']; +}; + + +export type MutationUpdateUserProfileArgs = { + data?: InputMaybe; + file?: InputMaybe; +}; + + +export type MutationUpdateUserTypeArgs = { + data: UpdateUserTypeInput; +}; + +export type OtpInput = { + email: Scalars['String']; +}; + +export type Organization = { + __typename?: 'Organization'; + _id: Scalars['ID']; + admins?: Maybe>>; + apiUrl: Scalars['String']; + blockedUsers?: Maybe>>; + createdAt?: Maybe; + creator: User; + description: Scalars['String']; + image?: Maybe; + isPublic: Scalars['Boolean']; + location?: Maybe; + members?: Maybe>>; + membershipRequests?: Maybe>>; + name: Scalars['String']; + tags: Array; + visibleInSearch: Scalars['Boolean']; +}; + + +export type OrganizationAdminsArgs = { + adminId?: InputMaybe; +}; + +export type OrganizationInfoNode = { + __typename?: 'OrganizationInfoNode'; + _id: Scalars['ID']; + apiUrl: Scalars['String']; + creator: User; + description: Scalars['String']; + image?: Maybe; + isPublic: Scalars['Boolean']; + name: Scalars['String']; + tags: Array; + visibleInSearch: Scalars['Boolean']; +}; + +export type OrganizationInput = { + apiUrl?: InputMaybe; + attendees?: InputMaybe; + description: Scalars['String']; + isPublic: Scalars['Boolean']; + location?: InputMaybe; + name: Scalars['String']; + visibleInSearch: Scalars['Boolean']; +}; + +export enum OrganizationOrderByInput { + ApiUrlAsc = 'apiUrl_ASC', + ApiUrlDesc = 'apiUrl_DESC', + DescriptionAsc = 'description_ASC', + DescriptionDesc = 'description_DESC', + IdAsc = 'id_ASC', + IdDesc = 'id_DESC', + NameAsc = 'name_ASC', + NameDesc = 'name_DESC' +} + +export type OrganizationWhereInput = { + apiUrl?: InputMaybe; + apiUrl_contains?: InputMaybe; + apiUrl_in?: InputMaybe>; + apiUrl_not?: InputMaybe; + apiUrl_not_in?: InputMaybe>; + apiUrl_starts_with?: InputMaybe; + description?: InputMaybe; + description_contains?: InputMaybe; + description_in?: InputMaybe>; + description_not?: InputMaybe; + description_not_in?: InputMaybe>; + description_starts_with?: InputMaybe; + id?: InputMaybe; + id_contains?: InputMaybe; + id_in?: InputMaybe>; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + id_starts_with?: InputMaybe; + isPublic?: InputMaybe; + name?: InputMaybe; + name_contains?: InputMaybe; + name_in?: InputMaybe>; + name_not?: InputMaybe; + name_not_in?: InputMaybe>; + name_starts_with?: InputMaybe; + visibleInSearch?: InputMaybe; +}; + +export type OtpData = { + __typename?: 'OtpData'; + otpToken: Scalars['String']; +}; + +/** Information about pagination in a connection. */ +export type PageInfo = { + __typename?: 'PageInfo'; + currPageNo?: Maybe; + /** When paginating forwards, are there more items? */ + hasNextPage: Scalars['Boolean']; + /** When paginating backwards, are there more items? */ + hasPreviousPage: Scalars['Boolean']; + nextPageNo?: Maybe; + prevPageNo?: Maybe; + totalPages?: Maybe; +}; + +export type Plugin = { + __typename?: 'Plugin'; + _id: Scalars['ID']; + installedOrgs: Array; + pluginCreatedBy: Scalars['String']; + pluginDesc: Scalars['String']; + pluginInstallStatus: Scalars['Boolean']; + pluginName: Scalars['String']; +}; + +export type PluginField = { + __typename?: 'PluginField'; + createdAt?: Maybe; + key: Scalars['String']; + status: Status; + value: Scalars['String']; +}; + +export type PluginFieldInput = { + key: Scalars['String']; + value: Scalars['String']; +}; + +export type PluginInput = { + fields?: InputMaybe>>; + orgId: Scalars['ID']; + pluginKey?: InputMaybe; + pluginName: Scalars['String']; + pluginType?: InputMaybe; +}; + +export type Post = { + __typename?: 'Post'; + _id?: Maybe; + commentCount?: Maybe; + comments?: Maybe>>; + createdAt?: Maybe; + creator: User; + imageUrl?: Maybe; + likeCount?: Maybe; + likedBy?: Maybe>>; + organization: Organization; + text: Scalars['String']; + title?: Maybe; + videoUrl?: Maybe; +}; + +/** A connection to a list of items. */ +export type PostConnection = { + __typename?: 'PostConnection'; + aggregate: AggregatePost; + /** A list of edges. */ + edges: Array>; + /** Information to aid in pagination. */ + pageInfo: PageInfo; +}; + +export type PostInput = { + _id?: InputMaybe; + imageUrl?: InputMaybe; + organizationId: Scalars['ID']; + text: Scalars['String']; + title?: InputMaybe; + videoUrl?: InputMaybe; +}; + +export enum PostOrderByInput { + CommentCountAsc = 'commentCount_ASC', + CommentCountDesc = 'commentCount_DESC', + CreatedAtAsc = 'createdAt_ASC', + CreatedAtDesc = 'createdAt_DESC', + IdAsc = 'id_ASC', + IdDesc = 'id_DESC', + ImageUrlAsc = 'imageUrl_ASC', + ImageUrlDesc = 'imageUrl_DESC', + LikeCountAsc = 'likeCount_ASC', + LikeCountDesc = 'likeCount_DESC', + TextAsc = 'text_ASC', + TextDesc = 'text_DESC', + TitleAsc = 'title_ASC', + TitleDesc = 'title_DESC', + VideoUrlAsc = 'videoUrl_ASC', + VideoUrlDesc = 'videoUrl_DESC' +} + +export type PostWhereInput = { + id?: InputMaybe; + id_contains?: InputMaybe; + id_in?: InputMaybe>; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + id_starts_with?: InputMaybe; + text?: InputMaybe; + text_contains?: InputMaybe; + text_in?: InputMaybe>; + text_not?: InputMaybe; + text_not_in?: InputMaybe>; + text_starts_with?: InputMaybe; + title?: InputMaybe; + title_contains?: InputMaybe; + title_in?: InputMaybe>; + title_not?: InputMaybe; + title_not_in?: InputMaybe>; + title_starts_with?: InputMaybe; +}; + +export type Query = { + __typename?: 'Query'; + adminPlugin?: Maybe>>; + checkAuth: User; + comments?: Maybe>>; + commentsByPost?: Maybe>>; + directChatMessages?: Maybe>>; + directChats?: Maybe>>; + directChatsByUserID?: Maybe>>; + directChatsMessagesByChatID?: Maybe>>; + event?: Maybe; + events?: Maybe>>; + eventsByOrganization?: Maybe>>; + getDonationById: Donation; + getDonationByOrgId?: Maybe>>; + getDonations?: Maybe>>; + getPlugins?: Maybe>>; + getlanguage?: Maybe>>; + groupChatMessages?: Maybe>>; + groupChats?: Maybe>>; + groups?: Maybe>>; + isUserRegister?: Maybe; + me: User; + myLanguage?: Maybe; + organizations?: Maybe>>; + organizationsConnection: Array>; + organizationsMemberConnection: UserConnection; + plugin?: Maybe>>; + post?: Maybe; + posts?: Maybe>>; + postsByOrganization?: Maybe>>; + postsByOrganizationConnection?: Maybe; + registeredEventsByUser?: Maybe>>; + registrantsByEvent?: Maybe>>; + tasksByEvent?: Maybe>>; + tasksByUser?: Maybe>>; + user: User; + userLanguage?: Maybe; + users?: Maybe>>; + usersConnection: Array>; +}; + + +export type QueryAdminPluginArgs = { + orgId: Scalars['ID']; +}; + + +export type QueryCommentsByPostArgs = { + id: Scalars['ID']; +}; + + +export type QueryDirectChatsByUserIdArgs = { + id: Scalars['ID']; +}; + + +export type QueryDirectChatsMessagesByChatIdArgs = { + id: Scalars['ID']; +}; + + +export type QueryEventArgs = { + id: Scalars['ID']; +}; + + +export type QueryEventsArgs = { + id?: InputMaybe; + orderBy?: InputMaybe; +}; + + +export type QueryEventsByOrganizationArgs = { + id?: InputMaybe; + orderBy?: InputMaybe; +}; + + +export type QueryGetDonationByIdArgs = { + id: Scalars['ID']; +}; + + +export type QueryGetDonationByOrgIdArgs = { + orgId: Scalars['ID']; +}; + + +export type QueryGetlanguageArgs = { + lang_code: Scalars['String']; +}; + + +export type QueryIsUserRegisterArgs = { + eventId: Scalars['ID']; +}; + + +export type QueryOrganizationsArgs = { + id?: InputMaybe; + orderBy?: InputMaybe; +}; + + +export type QueryOrganizationsConnectionArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + + +export type QueryOrganizationsMemberConnectionArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orgId: Scalars['ID']; + skip?: InputMaybe; + where?: InputMaybe; +}; + + +export type QueryPluginArgs = { + orgId: Scalars['ID']; +}; + + +export type QueryPostArgs = { + id: Scalars['ID']; +}; + + +export type QueryPostsArgs = { + orderBy?: InputMaybe; +}; + + +export type QueryPostsByOrganizationArgs = { + id: Scalars['ID']; + orderBy?: InputMaybe; +}; + + +export type QueryPostsByOrganizationConnectionArgs = { + first?: InputMaybe; + id: Scalars['ID']; + orderBy?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + + +export type QueryRegisteredEventsByUserArgs = { + id?: InputMaybe; + orderBy?: InputMaybe; +}; + + +export type QueryRegistrantsByEventArgs = { + id: Scalars['ID']; +}; + + +export type QueryTasksByEventArgs = { + id: Scalars['ID']; + orderBy?: InputMaybe; +}; + + +export type QueryTasksByUserArgs = { + id: Scalars['ID']; + orderBy?: InputMaybe; +}; + + +export type QueryUserArgs = { + id: Scalars['ID']; +}; + + +export type QueryUserLanguageArgs = { + userId: Scalars['ID']; +}; + + +export type QueryUsersArgs = { + orderBy?: InputMaybe; + where?: InputMaybe; +}; + + +export type QueryUsersConnectionArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + +export type RecaptchaVerification = { + recaptchaToken: Scalars['String']; +}; + +export enum Recurrance { + Daily = 'DAILY', + Monthly = 'MONTHLY', + Once = 'ONCE', + Weekly = 'WEEKLY', + Yearly = 'YEARLY' +} + +export enum Status { + Active = 'ACTIVE', + Blocked = 'BLOCKED', + Deleted = 'DELETED' +} + +export type Subscription = { + __typename?: 'Subscription'; + directMessageChat?: Maybe; + messageSentToDirectChat?: Maybe; + messageSentToGroupChat?: Maybe; +}; + +export type Task = { + __typename?: 'Task'; + _id: Scalars['ID']; + createdAt: Scalars['String']; + creator: User; + deadline?: Maybe; + description?: Maybe; + event: Event; + title: Scalars['String']; +}; + +export type TaskInput = { + deadline?: InputMaybe; + description?: InputMaybe; + title: Scalars['String']; +}; + +export enum TaskOrderByInput { + CreatedAtAsc = 'createdAt_ASC', + CreatedAtDesc = 'createdAt_DESC', + DeadlineAsc = 'deadline_ASC', + DeadlineDesc = 'deadline_DESC', + DescriptionAsc = 'description_ASC', + DescriptionDesc = 'description_DESC', + IdAsc = 'id_ASC', + IdDesc = 'id_DESC', + TitleAsc = 'title_ASC', + TitleDesc = 'title_DESC' +} + +export type Translation = { + __typename?: 'Translation'; + en_value?: Maybe; + lang_code?: Maybe; + translation?: Maybe; + verified?: Maybe; +}; + +export enum Type { + Private = 'PRIVATE', + Universal = 'UNIVERSAL' +} + +export type UpdateEventInput = { + allDay?: InputMaybe; + description?: InputMaybe; + endDate?: InputMaybe; + endTime?: InputMaybe; + isPublic?: InputMaybe; + isRegisterable?: InputMaybe; + latitude?: InputMaybe; + location?: InputMaybe; + longitude?: InputMaybe; + recurrance?: InputMaybe; + recurring?: InputMaybe; + startDate?: InputMaybe; + startTime?: InputMaybe; + title?: InputMaybe; +}; + +export type UpdateOrganizationInput = { + description?: InputMaybe; + isPublic?: InputMaybe; + name?: InputMaybe; + visibleInSearch?: InputMaybe; +}; + +export type UpdateTaskInput = { + deadline?: InputMaybe; + description?: InputMaybe; + title?: InputMaybe; +}; + +export type UpdateUserInput = { + email?: InputMaybe; + firstName?: InputMaybe; + lastName?: InputMaybe; +}; + +export type UpdateUserTypeInput = { + id?: InputMaybe; + userType?: InputMaybe; +}; + +export type User = { + __typename?: 'User'; + _id: Scalars['ID']; + adminApproved?: Maybe; + adminFor?: Maybe>>; + appLanguageCode: Scalars['String']; + createdAt?: Maybe; + createdEvents?: Maybe>>; + createdOrganizations?: Maybe>>; + email: Scalars['String']; + eventAdmin?: Maybe>>; + firstName: Scalars['String']; + image?: Maybe; + joinedOrganizations?: Maybe>>; + lastName: Scalars['String']; + membershipRequests?: Maybe>>; + organizationUserBelongsTo?: Maybe; + organizationsBlockedBy?: Maybe>>; + pluginCreationAllowed?: Maybe; + registeredEvents?: Maybe>>; + tokenVersion: Scalars['Int']; + userType?: Maybe; +}; + +export type UserAndOrganizationInput = { + organizationId: Scalars['ID']; + userId: Scalars['ID']; +}; + +export type UserAttende = { + __typename?: 'UserAttende'; + _id: Scalars['ID']; + createdAt?: Maybe; + status: Status; + user: User; + userId: Scalars['String']; +}; + +export type UserConnection = { + __typename?: 'UserConnection'; + aggregate: AggregateUser; + edges: Array>; + pageInfo: PageInfo; +}; + +export type UserInput = { + appLanguageCode?: InputMaybe; + email: Scalars['String']; + firstName: Scalars['String']; + lastName: Scalars['String']; + organizationUserBelongsToId?: InputMaybe; + password: Scalars['String']; + userType?: InputMaybe; +}; + +export enum UserOrderByInput { + AppLanguageCodeAsc = 'appLanguageCode_ASC', + AppLanguageCodeDesc = 'appLanguageCode_DESC', + EmailAsc = 'email_ASC', + EmailDesc = 'email_DESC', + FirstNameAsc = 'firstName_ASC', + FirstNameDesc = 'firstName_DESC', + IdAsc = 'id_ASC', + IdDesc = 'id_DESC', + LastNameAsc = 'lastName_ASC', + LastNameDesc = 'lastName_DESC' +} + +export enum UserType { + Admin = 'ADMIN', + Superadmin = 'SUPERADMIN', + User = 'USER' +} + +export type UserWhereInput = { + appLanguageCode?: InputMaybe; + appLanguageCode_contains?: InputMaybe; + appLanguageCode_in?: InputMaybe>; + appLanguageCode_not?: InputMaybe; + appLanguageCode_not_in?: InputMaybe>; + appLanguageCode_starts_with?: InputMaybe; + email?: InputMaybe; + email_contains?: InputMaybe; + email_in?: InputMaybe>; + email_not?: InputMaybe; + email_not_in?: InputMaybe>; + email_starts_with?: InputMaybe; + firstName?: InputMaybe; + firstName_contains?: InputMaybe; + firstName_in?: InputMaybe>; + firstName_not?: InputMaybe; + firstName_not_in?: InputMaybe>; + firstName_starts_with?: InputMaybe; + id?: InputMaybe; + id_contains?: InputMaybe; + id_in?: InputMaybe>; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + id_starts_with?: InputMaybe; + lastName?: InputMaybe; + lastName_contains?: InputMaybe; + lastName_in?: InputMaybe>; + lastName_not?: InputMaybe; + lastName_not_in?: InputMaybe>; + lastName_starts_with?: InputMaybe; +}; + +export type CreateChatInput = { + organizationId: Scalars['ID']; + userIds: Array; +}; + +export type CreateGroupChatInput = { + organizationId: Scalars['ID']; + title: Scalars['String']; + userIds: Array; +}; + + + +export type ResolverTypeWrapper = Promise | T; + +export type Resolver = ResolverFn; + +export type ResolverFn = ( + parent: TParent, + args: TArgs, + context: TContext, + info?: GraphQLResolveInfo +) => Promise | TResult; + +export type SubscriptionSubscribeFn = ( + parent: TParent, + args: TArgs, + context: TContext, + info?: GraphQLResolveInfo +) => AsyncIterable | Promise>; + +export type SubscriptionResolveFn = ( + parent: TParent, + args: TArgs, + context: TContext, + info?: GraphQLResolveInfo +) => TResult | Promise; + +export interface SubscriptionSubscriberObject { + subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>; + resolve?: SubscriptionResolveFn; +} + +export interface SubscriptionResolverObject { + subscribe: SubscriptionSubscribeFn; + resolve: SubscriptionResolveFn; +} + +export type SubscriptionObject = + | SubscriptionSubscriberObject + | SubscriptionResolverObject; + +export type SubscriptionResolver = + | ((...args: any[]) => SubscriptionObject) + | SubscriptionObject; + +export type TypeResolveFn = ( + parent: TParent, + context: TContext, + info?: GraphQLResolveInfo +) => Maybe | Promise>; + +export type IsTypeOfResolverFn = (obj: T, context: TContext, info?: GraphQLResolveInfo) => boolean | Promise; + +export type NextResolverFn = () => Promise; + +export type DirectiveResolverFn = ( + next: NextResolverFn, + parent: TParent, + args: TArgs, + context: TContext, + info?: GraphQLResolveInfo +) => TResult | Promise; + +/** Mapping between all available schema types and the resolvers types */ +export type ResolversTypes = { + AggregatePost: ResolverTypeWrapper; + AggregateUser: ResolverTypeWrapper; + AndroidFirebaseOptions: ResolverTypeWrapper; + AuthData: ResolverTypeWrapper & { user: ResolversTypes['User'] }>; + Boolean: ResolverTypeWrapper; + Comment: ResolverTypeWrapper; + CommentInput: CommentInput; + DeletePayload: ResolverTypeWrapper; + DirectChat: ResolverTypeWrapper; + DirectChatMessage: ResolverTypeWrapper; + Donation: ResolverTypeWrapper; + Event: ResolverTypeWrapper; + EventInput: EventInput; + EventOrderByInput: EventOrderByInput; + EventRegistrants: ResolverTypeWrapper & { event: ResolversTypes['Event'] }>; + ExtendSession: ResolverTypeWrapper; + Float: ResolverTypeWrapper; + ForgotPasswordData: ForgotPasswordData; + Group: ResolverTypeWrapper; + GroupChat: ResolverTypeWrapper; + GroupChatMessage: ResolverTypeWrapper; + GroupInput: GroupInput; + ID: ResolverTypeWrapper; + IOSFirebaseOptions: ResolverTypeWrapper; + Int: ResolverTypeWrapper; + Language: ResolverTypeWrapper; + LanguageInput: LanguageInput; + LanguageModel: ResolverTypeWrapper; + LoginInput: LoginInput; + MembershipRequest: ResolverTypeWrapper; + Message: ResolverTypeWrapper; + MessageChat: ResolverTypeWrapper; + MessageChatInput: MessageChatInput; + MultipleUsersAndOrganizationInput: MultipleUsersAndOrganizationInput; + Mutation: ResolverTypeWrapper<{}>; + OTPInput: OtpInput; + Organization: ResolverTypeWrapper; + OrganizationInfoNode: ResolverTypeWrapper & { creator: ResolversTypes['User'] }>; + OrganizationInput: OrganizationInput; + OrganizationOrderByInput: OrganizationOrderByInput; + OrganizationWhereInput: OrganizationWhereInput; + OtpData: ResolverTypeWrapper; + PageInfo: ResolverTypeWrapper; + Plugin: ResolverTypeWrapper; + PluginField: ResolverTypeWrapper; + PluginFieldInput: PluginFieldInput; + PluginInput: PluginInput; + Post: ResolverTypeWrapper; + PostConnection: ResolverTypeWrapper & { edges: Array> }>; + PostInput: PostInput; + PostOrderByInput: PostOrderByInput; + PostWhereInput: PostWhereInput; + Query: ResolverTypeWrapper<{}>; + RecaptchaVerification: RecaptchaVerification; + Recurrance: Recurrance; + Status: Status; + String: ResolverTypeWrapper; + Subscription: ResolverTypeWrapper<{}>; + Task: ResolverTypeWrapper; + TaskInput: TaskInput; + TaskOrderByInput: TaskOrderByInput; + Translation: ResolverTypeWrapper; + Type: Type; + UpdateEventInput: UpdateEventInput; + UpdateOrganizationInput: UpdateOrganizationInput; + UpdateTaskInput: UpdateTaskInput; + UpdateUserInput: UpdateUserInput; + UpdateUserTypeInput: UpdateUserTypeInput; + Upload: ResolverTypeWrapper; + User: ResolverTypeWrapper; + UserAndOrganizationInput: UserAndOrganizationInput; + UserAttende: ResolverTypeWrapper & { user: ResolversTypes['User'] }>; + UserConnection: ResolverTypeWrapper & { edges: Array> }>; + UserInput: UserInput; + UserOrderByInput: UserOrderByInput; + UserType: UserType; + UserWhereInput: UserWhereInput; + createChatInput: CreateChatInput; + createGroupChatInput: CreateGroupChatInput; +}; + +/** Mapping between all available schema types and the resolvers parents */ +export type ResolversParentTypes = { + AggregatePost: AggregatePost; + AggregateUser: AggregateUser; + AndroidFirebaseOptions: AndroidFirebaseOptions; + AuthData: Omit & { user: ResolversParentTypes['User'] }; + Boolean: Scalars['Boolean']; + Comment: Interface_Comment; + CommentInput: CommentInput; + DeletePayload: DeletePayload; + DirectChat: Interface_DirectChat; + DirectChatMessage: Interface_DirectChatMessage; + Donation: Interface_Donation; + Event: Interface_Event; + EventInput: EventInput; + EventRegistrants: Omit & { event: ResolversParentTypes['Event'] }; + ExtendSession: ExtendSession; + Float: Scalars['Float']; + ForgotPasswordData: ForgotPasswordData; + Group: Interface_Group; + GroupChat: Interface_GroupChat; + GroupChatMessage: Interface_GroupChatMessage; + GroupInput: GroupInput; + ID: Scalars['ID']; + IOSFirebaseOptions: IosFirebaseOptions; + Int: Scalars['Int']; + Language: Interface_Language; + LanguageInput: LanguageInput; + LanguageModel: LanguageModel; + LoginInput: LoginInput; + MembershipRequest: Interface_MembershipRequest; + Message: Interface_Message; + MessageChat: Interface_MessageChat; + MessageChatInput: MessageChatInput; + MultipleUsersAndOrganizationInput: MultipleUsersAndOrganizationInput; + Mutation: {}; + OTPInput: OtpInput; + Organization: Interface_Organization; + OrganizationInfoNode: Omit & { creator: ResolversParentTypes['User'] }; + OrganizationInput: OrganizationInput; + OrganizationWhereInput: OrganizationWhereInput; + OtpData: OtpData; + PageInfo: PageInfo; + Plugin: Interface_Plugin; + PluginField: Interface_PluginField; + PluginFieldInput: PluginFieldInput; + PluginInput: PluginInput; + Post: Interface_Post; + PostConnection: Omit & { edges: Array> }; + PostInput: PostInput; + PostWhereInput: PostWhereInput; + Query: {}; + RecaptchaVerification: RecaptchaVerification; + String: Scalars['String']; + Subscription: {}; + Task: Interface_Task; + TaskInput: TaskInput; + Translation: Translation; + UpdateEventInput: UpdateEventInput; + UpdateOrganizationInput: UpdateOrganizationInput; + UpdateTaskInput: UpdateTaskInput; + UpdateUserInput: UpdateUserInput; + UpdateUserTypeInput: UpdateUserTypeInput; + Upload: Scalars['Upload']; + User: Interface_User; + UserAndOrganizationInput: UserAndOrganizationInput; + UserAttende: Omit & { user: ResolversParentTypes['User'] }; + UserConnection: Omit & { edges: Array> }; + UserInput: UserInput; + UserWhereInput: UserWhereInput; + createChatInput: CreateChatInput; + createGroupChatInput: CreateGroupChatInput; +}; + +export type AuthDirectiveArgs = { }; + +export type AuthDirectiveResolver = DirectiveResolverFn; + +export type RoleDirectiveArgs = { + requires?: Maybe; +}; + +export type RoleDirectiveResolver = DirectiveResolverFn; + +export type AggregatePostResolvers = { + count?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type AggregateUserResolvers = { + count?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type AndroidFirebaseOptionsResolvers = { + apiKey?: Resolver, ParentType, ContextType>; + appId?: Resolver, ParentType, ContextType>; + messagingSenderId?: Resolver, ParentType, ContextType>; + projectId?: Resolver, ParentType, ContextType>; + storageBucket?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type AuthDataResolvers = { + accessToken?: Resolver; + androidFirebaseOptions?: Resolver; + iosFirebaseOptions?: Resolver; + refreshToken?: Resolver; + user?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type CommentResolvers = { + _id?: Resolver, ParentType, ContextType>; + createdAt?: Resolver, ParentType, ContextType>; + creator?: Resolver; + likeCount?: Resolver, ParentType, ContextType>; + likedBy?: Resolver>>, ParentType, ContextType>; + post?: Resolver; + text?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type DeletePayloadResolvers = { + success?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type DirectChatResolvers = { + _id?: Resolver; + creator?: Resolver; + messages?: Resolver>>, ParentType, ContextType>; + organization?: Resolver; + users?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type DirectChatMessageResolvers = { + _id?: Resolver; + createdAt?: Resolver; + directChatMessageBelongsTo?: Resolver; + messageContent?: Resolver; + receiver?: Resolver; + sender?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type DonationResolvers = { + _id?: Resolver; + amount?: Resolver; + nameOfOrg?: Resolver; + nameOfUser?: Resolver; + orgId?: Resolver; + payPalId?: Resolver; + userId?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type EventResolvers = { + _id?: Resolver; + admins?: Resolver>>, ParentType, ContextType, Partial>; + allDay?: Resolver; + creator?: Resolver; + description?: Resolver; + endDate?: Resolver; + endTime?: Resolver, ParentType, ContextType>; + isPublic?: Resolver; + isRegisterable?: Resolver; + latitude?: Resolver, ParentType, ContextType>; + location?: Resolver, ParentType, ContextType>; + longitude?: Resolver, ParentType, ContextType>; + organization?: Resolver, ParentType, ContextType>; + recurrance?: Resolver, ParentType, ContextType>; + recurring?: Resolver; + registrants?: Resolver>>, ParentType, ContextType>; + startDate?: Resolver; + startTime?: Resolver, ParentType, ContextType>; + status?: Resolver; + tasks?: Resolver>>, ParentType, ContextType>; + title?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type EventRegistrantsResolvers = { + event?: Resolver; + isRegistered?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type ExtendSessionResolvers = { + accessToken?: Resolver; + refreshToken?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type GroupResolvers = { + _id?: Resolver, ParentType, ContextType>; + admins?: Resolver>>, ParentType, ContextType>; + createdAt?: Resolver, ParentType, ContextType>; + description?: Resolver, ParentType, ContextType>; + organization?: Resolver; + title?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type GroupChatResolvers = { + _id?: Resolver; + creator?: Resolver; + messages?: Resolver>>, ParentType, ContextType>; + organization?: Resolver; + users?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type GroupChatMessageResolvers = { + _id?: Resolver; + createdAt?: Resolver; + groupChatMessageBelongsTo?: Resolver; + messageContent?: Resolver; + sender?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type IosFirebaseOptionsResolvers = { + apiKey?: Resolver, ParentType, ContextType>; + appId?: Resolver, ParentType, ContextType>; + iosBundleId?: Resolver, ParentType, ContextType>; + iosClientId?: Resolver, ParentType, ContextType>; + messagingSenderId?: Resolver, ParentType, ContextType>; + projectId?: Resolver, ParentType, ContextType>; + storageBucket?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type LanguageResolvers = { + _id?: Resolver; + createdAt?: Resolver; + en?: Resolver; + translation?: Resolver>>, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type LanguageModelResolvers = { + _id?: Resolver; + createdAt?: Resolver; + lang_code?: Resolver; + value?: Resolver; + verified?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type MembershipRequestResolvers = { + _id?: Resolver; + organization?: Resolver; + user?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type MessageResolvers = { + _id?: Resolver; + createdAt?: Resolver, ParentType, ContextType>; + creator?: Resolver, ParentType, ContextType>; + imageUrl?: Resolver, ParentType, ContextType>; + text?: Resolver, ParentType, ContextType>; + videoUrl?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type MessageChatResolvers = { + _id?: Resolver; + createdAt?: Resolver; + languageBarrier?: Resolver, ParentType, ContextType>; + message?: Resolver; + receiver?: Resolver; + sender?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type MutationResolvers = { + acceptAdmin?: Resolver>; + acceptMembershipRequest?: Resolver>; + addLanguageTranslation?: Resolver>; + addOrganizationImage?: Resolver>; + addUserImage?: Resolver>; + addUserToGroupChat?: Resolver>; + adminRemoveEvent?: Resolver>; + adminRemoveGroup?: Resolver>; + adminRemovePost?: Resolver>; + blockPluginCreationBySuperadmin?: Resolver>; + blockUser?: Resolver>; + cancelMembershipRequest?: Resolver>; + createAdmin?: Resolver>; + createComment?: Resolver, ParentType, ContextType, RequireFields>; + createDirectChat?: Resolver>; + createDonation?: Resolver>; + createEvent?: Resolver>; + createGroup?: Resolver>; + createGroupChat?: Resolver>; + createMessageChat?: Resolver>; + createOrganization?: Resolver>; + createPlugin?: Resolver>; + createPost?: Resolver, ParentType, ContextType, RequireFields>; + createTask?: Resolver>; + deleteDonationById?: Resolver>; + forgotPassword?: Resolver>; + joinPublicOrganization?: Resolver>; + leaveOrganization?: Resolver>; + likeComment?: Resolver, ParentType, ContextType, RequireFields>; + likePost?: Resolver, ParentType, ContextType, RequireFields>; + login?: Resolver>; + logout?: Resolver; + otp?: Resolver>; + recaptcha?: Resolver>; + refreshToken?: Resolver>; + registerForEvent?: Resolver>; + rejectAdmin?: Resolver>; + rejectMembershipRequest?: Resolver>; + removeAdmin?: Resolver>; + removeComment?: Resolver, ParentType, ContextType, RequireFields>; + removeDirectChat?: Resolver>; + removeEvent?: Resolver>; + removeGroupChat?: Resolver>; + removeMember?: Resolver>; + removeOrganization?: Resolver>; + removeOrganizationImage?: Resolver>; + removePost?: Resolver, ParentType, ContextType, RequireFields>; + removeTask?: Resolver, ParentType, ContextType, RequireFields>; + removeUserFromGroupChat?: Resolver>; + removeUserImage?: Resolver; + revokeRefreshTokenForUser?: Resolver>; + saveFcmToken?: Resolver>; + sendMembershipRequest?: Resolver>; + sendMessageToDirectChat?: Resolver>; + sendMessageToGroupChat?: Resolver>; + signUp?: Resolver>; + unblockUser?: Resolver>; + unlikeComment?: Resolver, ParentType, ContextType, RequireFields>; + unlikePost?: Resolver, ParentType, ContextType, RequireFields>; + unregisterForEventByUser?: Resolver>; + updateEvent?: Resolver>; + updateLanguage?: Resolver>; + updateOrganization?: Resolver>; + updatePluginInstalledOrgs?: Resolver>; + updatePluginStatus?: Resolver>; + updateTask?: Resolver, ParentType, ContextType, RequireFields>; + updateUserProfile?: Resolver>; + updateUserType?: Resolver>; +}; + +export type OrganizationResolvers = { + _id?: Resolver; + admins?: Resolver>>, ParentType, ContextType, Partial>; + apiUrl?: Resolver; + blockedUsers?: Resolver>>, ParentType, ContextType>; + createdAt?: Resolver, ParentType, ContextType>; + creator?: Resolver; + description?: Resolver; + image?: Resolver, ParentType, ContextType>; + isPublic?: Resolver; + location?: Resolver, ParentType, ContextType>; + members?: Resolver>>, ParentType, ContextType>; + membershipRequests?: Resolver>>, ParentType, ContextType>; + name?: Resolver; + tags?: Resolver, ParentType, ContextType>; + visibleInSearch?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type OrganizationInfoNodeResolvers = { + _id?: Resolver; + apiUrl?: Resolver; + creator?: Resolver; + description?: Resolver; + image?: Resolver, ParentType, ContextType>; + isPublic?: Resolver; + name?: Resolver; + tags?: Resolver, ParentType, ContextType>; + visibleInSearch?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type OtpDataResolvers = { + otpToken?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type PageInfoResolvers = { + currPageNo?: Resolver, ParentType, ContextType>; + hasNextPage?: Resolver; + hasPreviousPage?: Resolver; + nextPageNo?: Resolver, ParentType, ContextType>; + prevPageNo?: Resolver, ParentType, ContextType>; + totalPages?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type PluginResolvers = { + _id?: Resolver; + installedOrgs?: Resolver, ParentType, ContextType>; + pluginCreatedBy?: Resolver; + pluginDesc?: Resolver; + pluginInstallStatus?: Resolver; + pluginName?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type PluginFieldResolvers = { + createdAt?: Resolver, ParentType, ContextType>; + key?: Resolver; + status?: Resolver; + value?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type PostResolvers = { + _id?: Resolver, ParentType, ContextType>; + commentCount?: Resolver, ParentType, ContextType>; + comments?: Resolver>>, ParentType, ContextType>; + createdAt?: Resolver, ParentType, ContextType>; + creator?: Resolver; + imageUrl?: Resolver, ParentType, ContextType>; + likeCount?: Resolver, ParentType, ContextType>; + likedBy?: Resolver>>, ParentType, ContextType>; + organization?: Resolver; + text?: Resolver; + title?: Resolver, ParentType, ContextType>; + videoUrl?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type PostConnectionResolvers = { + aggregate?: Resolver; + edges?: Resolver>, ParentType, ContextType>; + pageInfo?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type QueryResolvers = { + adminPlugin?: Resolver>>, ParentType, ContextType, RequireFields>; + checkAuth?: Resolver; + comments?: Resolver>>, ParentType, ContextType>; + commentsByPost?: Resolver>>, ParentType, ContextType, RequireFields>; + directChatMessages?: Resolver>>, ParentType, ContextType>; + directChats?: Resolver>>, ParentType, ContextType>; + directChatsByUserID?: Resolver>>, ParentType, ContextType, RequireFields>; + directChatsMessagesByChatID?: Resolver>>, ParentType, ContextType, RequireFields>; + event?: Resolver, ParentType, ContextType, RequireFields>; + events?: Resolver>>, ParentType, ContextType, Partial>; + eventsByOrganization?: Resolver>>, ParentType, ContextType, Partial>; + getDonationById?: Resolver>; + getDonationByOrgId?: Resolver>>, ParentType, ContextType, RequireFields>; + getDonations?: Resolver>>, ParentType, ContextType>; + getPlugins?: Resolver>>, ParentType, ContextType>; + getlanguage?: Resolver>>, ParentType, ContextType, RequireFields>; + groupChatMessages?: Resolver>>, ParentType, ContextType>; + groupChats?: Resolver>>, ParentType, ContextType>; + groups?: Resolver>>, ParentType, ContextType>; + isUserRegister?: Resolver, ParentType, ContextType, RequireFields>; + me?: Resolver; + myLanguage?: Resolver, ParentType, ContextType>; + organizations?: Resolver>>, ParentType, ContextType, Partial>; + organizationsConnection?: Resolver>, ParentType, ContextType, Partial>; + organizationsMemberConnection?: Resolver>; + plugin?: Resolver>>, ParentType, ContextType, RequireFields>; + post?: Resolver, ParentType, ContextType, RequireFields>; + posts?: Resolver>>, ParentType, ContextType, Partial>; + postsByOrganization?: Resolver>>, ParentType, ContextType, RequireFields>; + postsByOrganizationConnection?: Resolver, ParentType, ContextType, RequireFields>; + registeredEventsByUser?: Resolver>>, ParentType, ContextType, Partial>; + registrantsByEvent?: Resolver>>, ParentType, ContextType, RequireFields>; + tasksByEvent?: Resolver>>, ParentType, ContextType, RequireFields>; + tasksByUser?: Resolver>>, ParentType, ContextType, RequireFields>; + user?: Resolver>; + userLanguage?: Resolver, ParentType, ContextType, RequireFields>; + users?: Resolver>>, ParentType, ContextType, Partial>; + usersConnection?: Resolver>, ParentType, ContextType, Partial>; +}; + +export type SubscriptionResolvers = { + directMessageChat?: SubscriptionResolver, "directMessageChat", ParentType, ContextType>; + messageSentToDirectChat?: SubscriptionResolver, "messageSentToDirectChat", ParentType, ContextType>; + messageSentToGroupChat?: SubscriptionResolver, "messageSentToGroupChat", ParentType, ContextType>; +}; + +export type TaskResolvers = { + _id?: Resolver; + createdAt?: Resolver; + creator?: Resolver; + deadline?: Resolver, ParentType, ContextType>; + description?: Resolver, ParentType, ContextType>; + event?: Resolver; + title?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type TranslationResolvers = { + en_value?: Resolver, ParentType, ContextType>; + lang_code?: Resolver, ParentType, ContextType>; + translation?: Resolver, ParentType, ContextType>; + verified?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export interface UploadScalarConfig extends GraphQLScalarTypeConfig { + name: 'Upload'; +} + +export type UserResolvers = { + _id?: Resolver; + adminApproved?: Resolver, ParentType, ContextType>; + adminFor?: Resolver>>, ParentType, ContextType>; + appLanguageCode?: Resolver; + createdAt?: Resolver, ParentType, ContextType>; + createdEvents?: Resolver>>, ParentType, ContextType>; + createdOrganizations?: Resolver>>, ParentType, ContextType>; + email?: Resolver; + eventAdmin?: Resolver>>, ParentType, ContextType>; + firstName?: Resolver; + image?: Resolver, ParentType, ContextType>; + joinedOrganizations?: Resolver>>, ParentType, ContextType>; + lastName?: Resolver; + membershipRequests?: Resolver>>, ParentType, ContextType>; + organizationUserBelongsTo?: Resolver, ParentType, ContextType>; + organizationsBlockedBy?: Resolver>>, ParentType, ContextType>; + pluginCreationAllowed?: Resolver, ParentType, ContextType>; + registeredEvents?: Resolver>>, ParentType, ContextType>; + tokenVersion?: Resolver; + userType?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type UserAttendeResolvers = { + _id?: Resolver; + createdAt?: Resolver, ParentType, ContextType>; + status?: Resolver; + user?: Resolver; + userId?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type UserConnectionResolvers = { + aggregate?: Resolver; + edges?: Resolver>, ParentType, ContextType>; + pageInfo?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type Resolvers = { + AggregatePost?: AggregatePostResolvers; + AggregateUser?: AggregateUserResolvers; + AndroidFirebaseOptions?: AndroidFirebaseOptionsResolvers; + AuthData?: AuthDataResolvers; + Comment?: CommentResolvers; + DeletePayload?: DeletePayloadResolvers; + DirectChat?: DirectChatResolvers; + DirectChatMessage?: DirectChatMessageResolvers; + Donation?: DonationResolvers; + Event?: EventResolvers; + EventRegistrants?: EventRegistrantsResolvers; + ExtendSession?: ExtendSessionResolvers; + Group?: GroupResolvers; + GroupChat?: GroupChatResolvers; + GroupChatMessage?: GroupChatMessageResolvers; + IOSFirebaseOptions?: IosFirebaseOptionsResolvers; + Language?: LanguageResolvers; + LanguageModel?: LanguageModelResolvers; + MembershipRequest?: MembershipRequestResolvers; + Message?: MessageResolvers; + MessageChat?: MessageChatResolvers; + Mutation?: MutationResolvers; + Organization?: OrganizationResolvers; + OrganizationInfoNode?: OrganizationInfoNodeResolvers; + OtpData?: OtpDataResolvers; + PageInfo?: PageInfoResolvers; + Plugin?: PluginResolvers; + PluginField?: PluginFieldResolvers; + Post?: PostResolvers; + PostConnection?: PostConnectionResolvers; + Query?: QueryResolvers; + Subscription?: SubscriptionResolvers; + Task?: TaskResolvers; + Translation?: TranslationResolvers; + Upload?: GraphQLScalarType; + User?: UserResolvers; + UserAttende?: UserAttendeResolvers; + UserConnection?: UserConnectionResolvers; +}; + +export type DirectiveResolvers = { + auth?: AuthDirectiveResolver; + role?: RoleDirectiveResolver; +}; diff --git a/lib/config/app.js b/src/lib/config/appConfig.ts similarity index 52% rename from lib/config/app.js rename to src/lib/config/appConfig.ts index 879c686afb..45ef049afb 100644 --- a/lib/config/app.js +++ b/src/lib/config/appConfig.ts @@ -1,7 +1,7 @@ -module.exports = { +export const appConfig = { env: process.env.NODE_ENV, colorize_logs: process.env.COLORIZE_LOGS, log_level: process.env.LOG_LEVEL, - defaultLocale: 'en', - supportedLocales: ['hi', 'en', 'zh', 'fr', 'sp'], + defaultLocale: "en", + supportedLocales: ["hi", "en", "zh", "fr", "sp"], }; diff --git a/firebaseOptions.js b/src/lib/config/firebaseConfig.ts similarity index 85% rename from firebaseOptions.js rename to src/lib/config/firebaseConfig.ts index ce23c02e12..15d91bb251 100644 --- a/firebaseOptions.js +++ b/src/lib/config/firebaseConfig.ts @@ -1,4 +1,4 @@ -module.exports.androidFirebaseOptions = { +export const androidFirebaseOptions = { apiKey: process.env.apiKey, appId: process.env.appId, messagingSenderId: process.env.messagingSenderId, @@ -6,7 +6,7 @@ module.exports.androidFirebaseOptions = { storageBucket: process.env.storageBucket, }; -module.exports.iosFirebaseOptions = { +export const iosFirebaseOptions = { apiKey: process.env.iOSapiKey, appId: process.env.iOSappId, messagingSenderId: process.env.iOSmessagingSenderId, diff --git a/src/lib/config/index.ts b/src/lib/config/index.ts new file mode 100644 index 0000000000..d6b960bc5c --- /dev/null +++ b/src/lib/config/index.ts @@ -0,0 +1,2 @@ +export * from "./appConfig"; +export * from "./firebaseConfig"; diff --git a/src/lib/directives/authDirective.ts b/src/lib/directives/authDirective.ts new file mode 100644 index 0000000000..ac063e9c34 --- /dev/null +++ b/src/lib/directives/authDirective.ts @@ -0,0 +1,35 @@ +import { SchemaDirectiveVisitor } from "apollo-server-express"; +import { + GraphQLInterfaceType, + GraphQLObjectType, + defaultFieldResolver, + GraphQLField, +} from "graphql"; +import { errors, requestContext } from "../libraries"; + +export class AuthenticationDirective extends SchemaDirectiveVisitor { + visitFieldDefinition( + field: GraphQLField, + /* + In typescript '_' as prefix of a function argument means that argument is + never used in the function definition. When the argument finds it's use + in the function definition '_' should be removed from the argument. + */ + _details: { + objectType: GraphQLObjectType | GraphQLInterfaceType; + } + ): GraphQLField | void | null { + const resolver = field.resolve || defaultFieldResolver; + + field.resolve = async (root, args, context, info) => { + if (context.expired || !context.isAuth) + throw new errors.UnauthenticatedError( + requestContext.translate("user.notAuthenticated"), + "user.notAuthenticated", + "userAuthentication" + ); + + return resolver(root, args, context, info); + }; + } +} diff --git a/src/lib/directives/index.ts b/src/lib/directives/index.ts new file mode 100644 index 0000000000..816ea6c9d5 --- /dev/null +++ b/src/lib/directives/index.ts @@ -0,0 +1,2 @@ +export * from "./authDirective"; +export * from "./roleDirective"; diff --git a/src/lib/directives/roleDirective.ts b/src/lib/directives/roleDirective.ts new file mode 100644 index 0000000000..b83071372d --- /dev/null +++ b/src/lib/directives/roleDirective.ts @@ -0,0 +1,58 @@ +import { SchemaDirectiveVisitor } from "apollo-server-express"; +import { + defaultFieldResolver, + GraphQLField, + GraphQLInterfaceType, + GraphQLObjectType, +} from "graphql"; +import { + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../constants"; +import { errors, requestContext } from "../libraries"; +import { User } from "../models"; + +export class RoleAuthorizationDirective extends SchemaDirectiveVisitor { + visitFieldDefinition( + field: GraphQLField, + /* + In typescript '_' as prefix of a function argument means that argument is + never used in the function definition. When the argument finds it's use + in the function definition '_' should be removed from the argument. + */ + _details: { + objectType: GraphQLObjectType | GraphQLInterfaceType; + } + ): GraphQLField | void | null { + const resolver = field.resolve || defaultFieldResolver; + + const { requires } = this.args; + + field.resolve = async (root, args, context, info) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + if (!currentUser) { + throw new errors.NotFoundError( + requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + if (currentUser.userType !== requires) { + throw new errors.UnauthenticatedError( + requestContext.translate("user.notAuthenticated"), + "user.notAuthenticated", + "userAuthentication" + ); + } + + context.user = currentUser; + + return resolver(root, args, context, info); + }; + } +} diff --git a/src/lib/libraries/errors/applicationError.ts b/src/lib/libraries/errors/applicationError.ts new file mode 100644 index 0000000000..69e2d26fa3 --- /dev/null +++ b/src/lib/libraries/errors/applicationError.ts @@ -0,0 +1,21 @@ +export interface Interface_Error { + message: string; + code: string | null; + param: string | null; + metadata?: Record; +} + +export class ApplicationError extends Error { + public errors: Interface_Error[]; + public httpCode: number; + + constructor( + errors: Interface_Error[], + httpCode: number = 422, + message: string = "Error" + ) { + super(message); + this.errors = errors; + this.httpCode = httpCode; + } +} diff --git a/src/lib/libraries/errors/conflictError.ts b/src/lib/libraries/errors/conflictError.ts new file mode 100644 index 0000000000..72a7ce9c49 --- /dev/null +++ b/src/lib/libraries/errors/conflictError.ts @@ -0,0 +1,20 @@ +import { ApplicationError } from "./applicationError"; + +export class ConflictError extends ApplicationError { + constructor( + message: string = "Conflicting entry found", + code: string | null = null, + param: string | null = null, + metadata: Record = {} + ) { + const errorJson = [ + { + message, + code, + param, + metadata, + }, + ]; + super(errorJson, 409, message); + } +} diff --git a/src/lib/libraries/errors/index.ts b/src/lib/libraries/errors/index.ts new file mode 100644 index 0000000000..a4f8a5dec8 --- /dev/null +++ b/src/lib/libraries/errors/index.ts @@ -0,0 +1,14 @@ +// Base class +export * from "./applicationError"; +// Used for resource already present +export * from "./conflictError"; +// Used for server fatal error +export * from "./internalServerError"; +// Used for resource not found +export * from "./notFoundError"; +// Used for invalid authentication token or wrong credentials +export * from "./unauthenticatedError"; +// Used for user is forbidden to perform operation +export * from "./unauthorizedError"; +// Used for basic sanity checks +export * from "./validationError"; diff --git a/src/lib/libraries/errors/internalServerError.ts b/src/lib/libraries/errors/internalServerError.ts new file mode 100644 index 0000000000..9fb464cde5 --- /dev/null +++ b/src/lib/libraries/errors/internalServerError.ts @@ -0,0 +1,20 @@ +import { ApplicationError } from "./applicationError"; + +export class InternalServerError extends ApplicationError { + constructor( + message: string = "Internal Server Error!", + code: string | null = null, + param: string | null = null, + metadata: Record = {} + ) { + const errorJson = [ + { + message, + code, + param, + metadata, + }, + ]; + super(errorJson, 500, message); + } +} diff --git a/src/lib/libraries/errors/notFoundError.ts b/src/lib/libraries/errors/notFoundError.ts new file mode 100644 index 0000000000..8ef626ba1f --- /dev/null +++ b/src/lib/libraries/errors/notFoundError.ts @@ -0,0 +1,20 @@ +import { ApplicationError } from "./applicationError"; + +export class NotFoundError extends ApplicationError { + constructor( + message: string = "Not Found", + code: string | null = null, + param: string | null = null, + metadata: Record = {} + ) { + const errorJson = [ + { + message, + code, + param, + metadata, + }, + ]; + super(errorJson, 404, message); + } +} diff --git a/src/lib/libraries/errors/unauthenticatedError.ts b/src/lib/libraries/errors/unauthenticatedError.ts new file mode 100644 index 0000000000..93e0642b18 --- /dev/null +++ b/src/lib/libraries/errors/unauthenticatedError.ts @@ -0,0 +1,20 @@ +import { ApplicationError } from "./applicationError"; + +export class UnauthenticatedError extends ApplicationError { + constructor( + message: string = "UnauthenticatedError", + code: string | null = null, + param: string | null = null, + metadata: Record = {} + ) { + const errorJson = [ + { + message, + code, + param, + metadata, + }, + ]; + super(errorJson, 401, message); + } +} diff --git a/src/lib/libraries/errors/unauthorizedError.ts b/src/lib/libraries/errors/unauthorizedError.ts new file mode 100644 index 0000000000..d411342c00 --- /dev/null +++ b/src/lib/libraries/errors/unauthorizedError.ts @@ -0,0 +1,20 @@ +import { ApplicationError } from "./applicationError"; + +export class UnauthorizedError extends ApplicationError { + constructor( + message: string = "UnauthorizedError", + code: string | null = null, + param: string | null = null, + metadata: Record = {} + ) { + const errorJson = [ + { + message, + code, + param, + metadata, + }, + ]; + super(errorJson, 403, message); + } +} diff --git a/src/lib/libraries/errors/validationError.ts b/src/lib/libraries/errors/validationError.ts new file mode 100644 index 0000000000..8280e4af39 --- /dev/null +++ b/src/lib/libraries/errors/validationError.ts @@ -0,0 +1,10 @@ +import { ApplicationError, Interface_Error } from "./applicationError"; + +export class ValidationError extends ApplicationError { + constructor( + errors: Interface_Error[] = [], + message: string = "Validation error" + ) { + super(errors, 422, message); + } +} diff --git a/src/lib/libraries/index.ts b/src/lib/libraries/index.ts new file mode 100644 index 0000000000..4c633e4375 --- /dev/null +++ b/src/lib/libraries/index.ts @@ -0,0 +1,4 @@ +export * as errors from "./errors"; +export * from "./logger"; +export * as requestContext from "./requestContext"; +export * as requestTracing from "./requestTracing"; diff --git a/src/lib/libraries/logger.ts b/src/lib/libraries/logger.ts new file mode 100644 index 0000000000..a2800d9f00 --- /dev/null +++ b/src/lib/libraries/logger.ts @@ -0,0 +1,56 @@ +import _ from "lodash"; +import { createLogger, transports, format } from "winston"; +import { getTracingId } from "./requestTracing"; +import { appConfig } from "../config"; + +const { combine, printf, splat, colorize, simple, timestamp } = format; + +const loggerFormat = printf((info) => { + let formatObject = `${info.level || "-"} ${info.timestamp || "-"} ${ + getTracingId() || "-" + } ${info.message} ${ + JSON.stringify(_.omit(info, ["level", "message", "stack", "timestamp"])) || + "-" + }`; + + if (info.stack) { + formatObject += `\n${info.stack}`; + } + return formatObject; +}); + +const formats = { + colorized: combine( + colorize(), + splat(), + simple(), + timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), + loggerFormat + ), + non_colorized: combine( + splat(), + simple(), + timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), + loggerFormat + ), +}; + +export const logger = createLogger({ + transports: [ + new transports.Console({ + level: appConfig.log_level, + format: + appConfig.colorize_logs === "true" + ? formats.colorized + : formats.non_colorized, + }), + ], +}); + +// Invalid code. Currently ignored by typescript. Needs fix. +logger.stream = { + // @ts-ignore + write: (message) => { + logger.info((message || "").trim()); + }, +}; diff --git a/src/lib/libraries/requestContext.ts b/src/lib/libraries/requestContext.ts new file mode 100644 index 0000000000..9644d71c8d --- /dev/null +++ b/src/lib/libraries/requestContext.ts @@ -0,0 +1,72 @@ +import cls from "cls-hooked"; +// No type defintions available for package 'cls-bluebird' +// @ts-ignore +import clsBluebird from "cls-bluebird"; +import i18n from "i18n"; +import { NextFunction, Request, Response } from "express"; + +const requestContextNamespace = cls.createNamespace("talawa-request-context"); + +clsBluebird(requestContextNamespace); + +const setRequestContextValue = (key: string, value: T) => { + return requestContextNamespace.set(key, value); +}; + +const getRequestContextValue = (key: string) => { + return requestContextNamespace.get(key); +}; + +const setRequestContext = (obj: any) => { + setRequestContextValue("translate", obj.__); + setRequestContextValue("translatePlural", obj.__n); +}; + +export const middleware = () => { + return (req: Request, res: Response, next: NextFunction) => { + requestContextNamespace.bindEmitter(req); + requestContextNamespace.bindEmitter(res); + + requestContextNamespace.run(() => { + setRequestContext(req); + next(); + }); + }; +}; + +interface Interface_InitOptions extends Record { + requestHandler?: () => T; +} + +// Invalid code. Currently ignored by typescript. Needs fix. +export const init = async (options: Interface_InitOptions = {}) => { + const obj: any = {}; + // @ts-ignore + i18n.init(obj); + // @ts-ignore + obj.setLocale(options.lang); + return requestContextNamespace.runAndReturn(() => { + setRequestContext({ + __: obj.__, + __n: obj.__n, + }); + // @ts-ignore + return options.requestHandler(); + }); +}; + +export const translate = (...args: any) => { + const __ = getRequestContextValue("translate"); + if (typeof __ !== "function") { + throw new Error("i18n is not initialized, try app.use(i18n.init);"); + } + return __(...args); +}; + +export const translatePlural = (...args: any) => { + const __n = getRequestContextValue("translatePlural"); + if (typeof __n !== "function") { + throw new Error("i18n is not initialized, try app.use(i18n.init);"); + } + return __n(...args); +}; diff --git a/src/lib/libraries/requestTracing.ts b/src/lib/libraries/requestTracing.ts new file mode 100644 index 0000000000..0cd4620b96 --- /dev/null +++ b/src/lib/libraries/requestTracing.ts @@ -0,0 +1,55 @@ +import cls from "cls-hooked"; +// No type defintions available for package 'cls-bluebird' +// @ts-ignore +import clsBluebird from "cls-bluebird"; +import { customAlphabet } from "nanoid"; +import { NextFunction, Request, Response } from "express"; + +// Alphabets used in the custom nanoid function +const alphabets = "0123456789abcdefghijklmnopqrstuvwxyz"; + +/* +Custom nanoid function to generate a unique 10 characters request ID +using the characters in alphabets variable +*/ +const nanoid = customAlphabet(alphabets, 10); + +const requestTracingNamespace = cls.createNamespace("request-tracing"); + +clsBluebird(requestTracingNamespace); + +export const tracingIdHeaderName = "X-Tracing-Id"; + +const tracingIdContextKeyName = "tracingId"; + +const setTracingId = (tracingId: string) => { + return requestTracingNamespace.set(tracingIdContextKeyName, tracingId); +}; + +export const getTracingId = () => { + return requestTracingNamespace.get(tracingIdContextKeyName) as string; +}; + +export const middleware = () => { + return (req: Request, res: Response, next: NextFunction) => { + requestTracingNamespace.bindEmitter(req); + requestTracingNamespace.bindEmitter(res); + + const tracingId = req.header(tracingIdHeaderName) || nanoid(); + // We need to set header to ensure API gateway which proxies request, forwards the header as well + req.headers[tracingIdHeaderName] = tracingId; + res.header(tracingIdHeaderName, tracingId); // Adding tracing ID to response headers + + requestTracingNamespace.run(() => { + setTracingId(tracingId); + next(); + }); + }; +}; + +export const trace = async (tracingId: string, method: () => T) => { + await requestTracingNamespace.runAndReturn(() => { + setTracingId(tracingId || nanoid()); + return method(); + }); +}; diff --git a/src/lib/middleware/index.ts b/src/lib/middleware/index.ts new file mode 100644 index 0000000000..7f43ff4d06 --- /dev/null +++ b/src/lib/middleware/index.ts @@ -0,0 +1 @@ +export * from "./isAuth"; diff --git a/src/lib/middleware/isAuth.ts b/src/lib/middleware/isAuth.ts new file mode 100644 index 0000000000..64e5bad0d4 --- /dev/null +++ b/src/lib/middleware/isAuth.ts @@ -0,0 +1,80 @@ +import jwt from "jsonwebtoken"; +import { Request } from "express"; +import { logger } from "../libraries"; + +// This interface represents the type of data object returned by isAuth function. +export interface Interface_AuthData { + isAuth: boolean; + expired: boolean | undefined; + userId: string | undefined; +} + +export const isAuth = (request: Request) => { + /* + This object is the return value of this function. Mutate the fields of this + object conditionally as the authentication flow continues and return it from + the function whereever needed. + */ + const authData: Interface_AuthData = { + isAuth: false, + expired: undefined, + userId: undefined, + }; + + // This checks to see if there is an authorization field within the incoming request + const authHeader = request.headers.authorization; + + // If no authorization header was sent from the client + if (!authHeader) { + return authData; + } + + // format of request sent will be Bearer tokenvalue + // this splits it into two values bearer and the token + const token = authHeader.split(" ")[1]; + + // if the token is null or an empty string + if (!token || token === "") { + return authData; + } + + // uses key created in the auth resolver + // to be changed in production + // only tokens created with this key will be valid tokens + let decodedToken: any; + try { + decodedToken = jwt.verify( + token, + process.env.ACCESS_TOKEN_SECRET as string, + (err, decoded) => { + if (err) { + return err; + } + + return decoded; + } + ); // If there is an error decoded token would contain it + + if (decodedToken.name === "TokenExpiredError") { + // If the token has expired set the expired field of authData to true and return it + authData.expired = true; + return authData; + } + } catch (e) { + authData.expired = true; + return authData; + } + + // if the decoded token is not set + if (!decodedToken) { + logger.info("decoded token is not present"); + return authData; + } + + // shows the user is an authenticated user + authData.isAuth = true; + // pulls user data(userId) out of the token and attaches it to userId field of authData object + authData.userId = decodedToken.userId; + + return authData; +}; diff --git a/src/lib/models/Comment.ts b/src/lib/models/Comment.ts new file mode 100644 index 0000000000..0e928b38b2 --- /dev/null +++ b/src/lib/models/Comment.ts @@ -0,0 +1,58 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_Post } from "./Post"; +import { Interface_User } from "./User"; + +export interface Interface_Comment { + _id: Types.ObjectId; + text: string; + createdAt: Date; + creator: PopulatedDoc; + post: PopulatedDoc; + likedBy: Array>; + likeCount: number; + status: string; +} + +const commentSchema = new Schema({ + text: { + type: String, + required: true, + }, + createdAt: { + type: Date, + default: Date.now, + }, + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + post: { + type: Schema.Types.ObjectId, + ref: "Post", + required: true, + }, + likedBy: [ + { + type: Schema.Types.ObjectId, + ref: "User", + }, + ], + likeCount: { + type: Number, + default: 0, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const CommentModel = () => model("Comment", commentSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Comment = (models.Comment || CommentModel()) as ReturnType< + typeof CommentModel +>; diff --git a/src/lib/models/DirectChat.ts b/src/lib/models/DirectChat.ts new file mode 100644 index 0000000000..43e9f687dd --- /dev/null +++ b/src/lib/models/DirectChat.ts @@ -0,0 +1,52 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_DirectChatMessage } from "./DirectChatMessage"; +import { Interface_Organization } from "./Organization"; +import { Interface_User } from "./User"; + +export interface Interface_DirectChat { + _id: Types.ObjectId; + users: Array>; + messages: Array>; + creator: PopulatedDoc; + organization: PopulatedDoc; + status: string; +} + +const directChatSchema = new Schema({ + users: [ + { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + ], + messages: [ + { + type: Schema.Types.ObjectId, + ref: "DirectChatMessage", + }, + ], + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const DirectChatModel = () => + model("DirectChat", directChatSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const DirectChat = (models.DirectChat || + DirectChatModel()) as ReturnType; diff --git a/src/lib/models/DirectChatMessage.ts b/src/lib/models/DirectChatMessage.ts new file mode 100644 index 0000000000..2508a85b69 --- /dev/null +++ b/src/lib/models/DirectChatMessage.ts @@ -0,0 +1,55 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_DirectChat } from "./DirectChat"; +import { Interface_User } from "./User"; + +export interface Interface_DirectChatMessage { + _id: Types.ObjectId; + directChatMessageBelongsTo: PopulatedDoc; + sender: PopulatedDoc; + receiver: PopulatedDoc; + createdAt: Date; + messageContent: string; + status: string; +} + +const directChatMessageSchema = new Schema({ + directChatMessageBelongsTo: { + type: Schema.Types.ObjectId, + ref: "DirectChat", + required: true, + }, + sender: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + receiver: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + createdAt: { + type: Date, + required: true, + }, + messageContent: { + type: String, + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const DirectChatMessageModel = () => + model( + "DirectChatMessage", + directChatMessageSchema + ); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const DirectChatMessage = (models.DirectChatMessage || + DirectChatMessageModel()) as ReturnType; diff --git a/src/lib/models/Donation.ts b/src/lib/models/Donation.ts new file mode 100644 index 0000000000..c89dc389be --- /dev/null +++ b/src/lib/models/Donation.ts @@ -0,0 +1,45 @@ +import { Schema, model, Types, models } from "mongoose"; + +export interface Interface_Donation { + userId: Types.ObjectId | string; + orgId: Types.ObjectId | string; + nameOfOrg: string; + payPalId: string; + nameOfUser: string; + amount: number; +} + +const donationSchema = new Schema({ + userId: { + type: Schema.Types.ObjectId, + required: true, + }, + orgId: { + type: Schema.Types.ObjectId, + required: true, + }, + nameOfOrg: { + type: String, + required: true, + }, + payPalId: { + type: String, + required: true, + }, + nameOfUser: { + type: String, + required: true, + }, + amount: { + type: Number, + required: true, + }, +}); + +const DonationModel = () => + model("Donation", donationSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Donation = (models.Donation || DonationModel()) as ReturnType< + typeof DonationModel +>; diff --git a/src/lib/models/Event.ts b/src/lib/models/Event.ts new file mode 100644 index 0000000000..24e3d04bd4 --- /dev/null +++ b/src/lib/models/Event.ts @@ -0,0 +1,172 @@ +import { Schema, Types, model, PopulatedDoc, Document, models } from "mongoose"; +import { Interface_Organization } from "./Organization"; +import { Interface_Task } from "./Task"; +import { Interface_User } from "./User"; + +export interface Interface_UserAttende { + userId: string; + user: PopulatedDoc; + status: string; + createdAt: Date; +} + +const userAttendeSchema = new Schema({ + userId: { + type: String, + required: true, + }, + user: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, + createdAt: { + type: Date, + default: Date.now, + }, +}); + +export interface Interface_Event { + _id: Types.ObjectId; + title: string; + description: string; + attendees: string | undefined; + location: string | undefined; + latitude: number | undefined; + longitude: number; + recurring: boolean; + allDay: boolean; + startDate: string; + endDate: string | undefined; + startTime: string | undefined; + endTime: string | undefined; + recurrance: string; + isPublic: boolean; + isRegisterable: boolean; + creator: PopulatedDoc; + registrants: Array>; + admins: Array>; + organization: PopulatedDoc; + tasks: Array>; + status: string; +} + +const eventSchema = new Schema({ + title: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + attendees: { + type: String, + required: false, + }, + location: { + type: String, + }, + latitude: { + type: Number, + required: false, + }, + longitude: { + type: Number, + required: false, + }, + recurring: { + type: Boolean, + required: true, + default: false, + }, + allDay: { + type: Boolean, + required: true, + }, + startDate: { + type: String, + required: true, + }, + endDate: { + type: String, + required: function () { + // @ts-ignore + return !this.allDay; + }, + }, + startTime: { + type: String, + required: function () { + // @ts-ignore + return !this.allDay; + }, + }, + endTime: { + type: String, + required: function () { + // @ts-ignore + return !this.allDay; + }, + }, + recurrance: { + type: String, + required: function () { + // @ts-ignore + return this.recurring; + }, + enum: ["ONCE", "DAILY", "WEEKLY", "MONTHLY", "YEARLY"], + default: "ONCE", + }, + isPublic: { + type: Boolean, + required: true, + }, + isRegisterable: { + type: Boolean, + required: true, + }, + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + registrants: [userAttendeSchema], + admins: [ + { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + ], + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + tasks: [ + { + type: Schema.Types.ObjectId, + ref: "Task", + }, + ], + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const EventModel = () => model("Event", eventSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Event = (models.Event || EventModel()) as ReturnType< + typeof EventModel +>; diff --git a/src/lib/models/EventProject.ts b/src/lib/models/EventProject.ts new file mode 100644 index 0000000000..0a0b5e053e --- /dev/null +++ b/src/lib/models/EventProject.ts @@ -0,0 +1,59 @@ +import { Schema, Types, model, PopulatedDoc, Document, models } from "mongoose"; +import { Interface_Event } from "./Event"; +import { Interface_Task } from "./Task"; +import { Interface_User } from "./User"; + +export interface Interface_EventProject { + _id: Types.ObjectId; + title: string; + description: string; + createdAt: Date; + event: PopulatedDoc; + creator: PopulatedDoc; + tasks: Array>; + status: string; +} + +const eventProjectSchema = new Schema({ + title: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + createdAt: { + type: Date, + default: Date.now, + }, + event: { + type: Schema.Types.ObjectId, + ref: "Event", + required: true, + }, + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + tasks: [ + { + type: Schema.Types.ObjectId, + ref: "Task", + }, + ], + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const EventProjectModel = () => + model("EventProject", eventProjectSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const EventProject = (models.EventProject || + EventProjectModel()) as ReturnType; diff --git a/src/lib/models/File.ts b/src/lib/models/File.ts new file mode 100644 index 0000000000..1b9ab9cc9b --- /dev/null +++ b/src/lib/models/File.ts @@ -0,0 +1,52 @@ +import { Schema, model, Types, models } from "mongoose"; +import { v4 as uuidv4 } from "uuid"; + +export interface Interface_File { + _id: Types.ObjectId; + name: string; + url: string | undefined; + size: number | undefined; + secret: string; + createdAt: Date; + contentType: string | undefined; + status: string; +} + +const fileSchema = new Schema({ + name: { + type: String, + required: true, + default: uuidv4(), + }, + url: { + type: String, + }, + size: { + type: Number, + }, + secret: { + type: String, + required: true, + }, + createdAt: { + type: Date, + required: true, + default: Date.now, + }, + contentType: { + type: String, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const FileModel = () => model("File", fileSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const File = (models.File || FileModel()) as ReturnType< + typeof FileModel +>; diff --git a/src/lib/models/Group.ts b/src/lib/models/Group.ts new file mode 100644 index 0000000000..a451f37b91 --- /dev/null +++ b/src/lib/models/Group.ts @@ -0,0 +1,52 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_Organization } from "./Organization"; +import { Interface_User } from "./User"; + +export interface Interface_Group { + _id: Types.ObjectId; + title: string; + description: string | undefined; + createdAt: Date; + organization: PopulatedDoc; + status: string; + admins: Array>; +} + +const groupSchema = new Schema({ + title: { + type: String, + required: true, + }, + description: { + type: String, + }, + createdAt: { + type: Date, + default: Date.now, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, + admins: [ + { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + ], +}); + +const GroupModel = () => model("Group", groupSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Group = (models.Group || GroupModel()) as ReturnType< + typeof GroupModel +>; diff --git a/src/lib/models/GroupChat.ts b/src/lib/models/GroupChat.ts new file mode 100644 index 0000000000..1611154357 --- /dev/null +++ b/src/lib/models/GroupChat.ts @@ -0,0 +1,58 @@ +import { Schema, Types, model, PopulatedDoc, Document, models } from "mongoose"; +import { Interface_GroupChatMessage } from "./GroupChatMessage"; +import { Interface_Organization } from "./Organization"; +import { Interface_User } from "./User"; + +export interface Interface_GroupChat { + _id: Types.ObjectId; + title: string; + users: Array>; + messages: Array>; + creator: PopulatedDoc; + organization: PopulatedDoc; + status: string; +} + +const groupChatSchema = new Schema({ + title: { + type: String, + required: true, + }, + users: [ + { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + ], + messages: [ + { + type: Schema.Types.ObjectId, + ref: "GroupChatMessage", + }, + ], + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const GroupChatModel = () => + model("GroupChat", groupChatSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const GroupChat = (models.GroupChat || GroupChatModel()) as ReturnType< + typeof GroupChatModel +>; diff --git a/src/lib/models/GroupChatMessage.ts b/src/lib/models/GroupChatMessage.ts new file mode 100644 index 0000000000..d50e12733e --- /dev/null +++ b/src/lib/models/GroupChatMessage.ts @@ -0,0 +1,46 @@ +import { Schema, Types, model, PopulatedDoc, Document, models } from "mongoose"; +import { Interface_GroupChat } from "./GroupChat"; +import { Interface_User } from "./User"; + +export interface Interface_GroupChatMessage { + _id: Types.ObjectId; + groupChatMessageBelongsTo: PopulatedDoc; + sender: PopulatedDoc; + createdAt: Date; + messageContent: string; + status: string; +} + +const groupChatMessageSchema = new Schema({ + groupChatMessageBelongsTo: { + type: Schema.Types.ObjectId, + ref: "GroupChat", + required: true, + }, + sender: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + createdAt: { + type: Date, + required: true, + }, + messageContent: { + type: String, + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const GroupChatMessageModel = () => + model("GroupChatMessage", groupChatMessageSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const GroupChatMessage = (models.GroupChatMessage || + GroupChatMessageModel()) as ReturnType; diff --git a/src/lib/models/ImageHash.ts b/src/lib/models/ImageHash.ts new file mode 100644 index 0000000000..15f94c935a --- /dev/null +++ b/src/lib/models/ImageHash.ts @@ -0,0 +1,39 @@ +import { Schema, model, Types, models } from "mongoose"; + +export interface Interface_ImageHash { + _id: Types.ObjectId; + hashValue: string; + fileName: string; + numberOfUses: number; + status: string; +} + +const imageHashSchema = new Schema({ + hashValue: { + type: String, + required: true, + }, + fileName: { + type: String, + required: true, + }, + numberOfUses: { + type: Number, + default: 0, + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const ImageHashModel = () => + model("ImageHash", imageHashSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const ImageHash = (models.ImageHash || ImageHashModel()) as ReturnType< + typeof ImageHashModel +>; diff --git a/src/lib/models/Language.ts b/src/lib/models/Language.ts new file mode 100644 index 0000000000..33101cb519 --- /dev/null +++ b/src/lib/models/Language.ts @@ -0,0 +1,62 @@ +import { Schema, model, Types, Document, PopulatedDoc, models } from "mongoose"; + +export interface Interface_LanguageModel { + lang_code: string; + value: string; + verified: boolean; + createdAt: Date; +} + +const languageModelSchema = new Schema({ + lang_code: { + type: String, + required: true, + unique: false, + lowercase: true, + }, + value: { + type: String, + required: true, + lowercase: true, + }, + verified: { + type: Boolean, + required: true, + default: false, + }, + createdAt: { + type: Date, + required: true, + default: Date.now, + }, +}); + +export interface Interface_Language { + _id: Types.ObjectId; + en: string; + translation: Array>; + createdAt: Date; +} + +const languageSchema = new Schema({ + en: { + type: String, + required: true, + unique: true, + lowercase: true, + }, + translation: [languageModelSchema], + createdAt: { + type: Date, + required: true, + default: Date.now, + }, +}); + +const LanguageModel = () => + model("Language", languageSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Language = (models.Language || LanguageModel()) as ReturnType< + typeof LanguageModel +>; diff --git a/src/lib/models/MembershipRequest.ts b/src/lib/models/MembershipRequest.ts new file mode 100644 index 0000000000..6be4a7ea69 --- /dev/null +++ b/src/lib/models/MembershipRequest.ts @@ -0,0 +1,38 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_Organization } from "./Organization"; +import { Interface_User } from "./User"; + +export interface Interface_MembershipRequest { + _id: Types.ObjectId; + organization: PopulatedDoc; + user: PopulatedDoc | undefined; + status: string; +} + +const membershipRequestSchema = new Schema({ + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + user: { + type: Schema.Types.ObjectId, + ref: "User", + }, + status: { + type: String, + required: true, + default: "ACTIVE", + enum: ["ACTIVE", "BLOCKED", "DELETED"], + }, +}); + +const MembershipRequestModel = () => + model( + "MembershipRequest", + membershipRequestSchema + ); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const MembershipRequest = (models.MembershipRequest || + MembershipRequestModel()) as ReturnType; diff --git a/src/lib/models/Message.ts b/src/lib/models/Message.ts new file mode 100644 index 0000000000..73b364e91f --- /dev/null +++ b/src/lib/models/Message.ts @@ -0,0 +1,56 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_Group } from "./Group"; +import { Interface_User } from "./User"; + +export interface Interface_Message { + _id: Types.ObjectId; + text: string; + imageUrl: string | undefined; + videoUrl: string | undefined; + createdAt: Date; + creator: PopulatedDoc; + group: PopulatedDoc; + status: string; +} + +const messageSchema = new Schema({ + text: { + type: String, + required: true, + }, + imageUrl: { + type: String, + required: false, + }, + videoUrl: { + type: String, + required: false, + }, + createdAt: { + type: Date, + default: Date.now, + }, + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + group: { + type: Schema.Types.ObjectId, + ref: "Group", + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, +}); + +const MessageModel = () => model("Message", messageSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Message = (models.Message || MessageModel()) as ReturnType< + typeof MessageModel +>; diff --git a/src/lib/models/MessageChat.ts b/src/lib/models/MessageChat.ts new file mode 100644 index 0000000000..7a3fad27ef --- /dev/null +++ b/src/lib/models/MessageChat.ts @@ -0,0 +1,45 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_User } from "./User"; + +export interface Interface_MessageChat { + _id: Types.ObjectId; + message: string; + languageBarrier: boolean; + sender: PopulatedDoc; + receiver: PopulatedDoc; + createdAt: Date; +} + +const messageChatSchema = new Schema({ + message: { + type: String, + required: true, + }, + languageBarrier: { + type: Boolean, + required: false, + default: false, + }, + sender: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + receiver: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + createdAt: { + type: Date, + required: true, + default: Date.now, + }, +}); + +const MessageChatModel = () => + model("MessageChat", messageChatSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const MessageChat = (models.MessageChat || + MessageChatModel()) as ReturnType; diff --git a/src/lib/models/Organization.ts b/src/lib/models/Organization.ts new file mode 100644 index 0000000000..beba57088f --- /dev/null +++ b/src/lib/models/Organization.ts @@ -0,0 +1,118 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { MembershipRequest } from "../../generated/graphqlCodegen"; +import { Interface_Message } from "./Message"; +import { Interface_Post } from "./Post"; +import { Interface_User } from "./User"; + +export interface Interface_Organization { + _id: Types.ObjectId; + apiUrl: string | undefined; + image: string | undefined; + name: string; + description: string; + location: string | undefined; + isPublic: boolean; + creator: PopulatedDoc; + status: string; + members: Array>; + admins: Array>; + groupChats: Array>; + posts: Array>; + membershipRequests: Array>; + blockedUsers: Array>; + visibleInSearch: boolean | undefined; + tags: Array; + createdAt: Date; +} + +const organizationSchema = new Schema({ + apiUrl: { + type: String, + }, + image: { + type: String, + }, + name: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + location: { + type: String, + }, + isPublic: { + type: Boolean, + required: true, + }, + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, + members: [ + { + type: Schema.Types.ObjectId, + ref: "User", + }, + ], + admins: [ + { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + ], + groupChats: [ + { + type: Schema.Types.ObjectId, + ref: "Message", + }, + ], + posts: [ + { + type: Schema.Types.ObjectId, + ref: "Post", + }, + ], + membershipRequests: [ + { + type: Schema.Types.ObjectId, + ref: "MembershipRequest", + }, + ], + blockedUsers: [ + { + type: Schema.Types.ObjectId, + ref: "User", + }, + ], + visibleInSearch: { + type: Boolean, + }, + tags: [ + { + type: String, + required: false, + }, + ], + createdAt: { + type: Date, + default: Date.now, + }, +}); + +const OrganizationModel = () => + model("Organization", organizationSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Organization = (models.Organization || + OrganizationModel()) as ReturnType; diff --git a/lib/models/Plugin.js b/src/lib/models/Plugin.ts similarity index 56% rename from lib/models/Plugin.js rename to src/lib/models/Plugin.ts index aa6b00f76d..54681fc819 100644 --- a/lib/models/Plugin.js +++ b/src/lib/models/Plugin.ts @@ -1,5 +1,14 @@ -const mongoose = require('mongoose'); -const Schema = mongoose.Schema; +import { Schema, Types, model, models } from "mongoose"; + +export interface Interface_Plugin { + _id: Types.ObjectId; + pluginName: string; + pluginCreatedBy: string; + pluginDesc: string; + pluginInstallStatus: boolean; + installedOrgs: Array; +} + /** * @name pluginSchema * @description Schema for MongoDB database @@ -9,6 +18,7 @@ const Schema = mongoose.Schema; * @param {Boolean} pluginInstallStatus shows if the plugin is enabled or not * @param {String[]} installedOrgs list of orgIDs on which the plugin is enabled */ + const pluginSchema = new Schema({ pluginName: { type: String, @@ -28,8 +38,17 @@ const pluginSchema = new Schema({ default: false, }, installedOrgs: [ - { type: Schema.Types.ObjectId, required: false, default: [] }, + { + type: Schema.Types.ObjectId, + required: false, + default: [], + }, ], }); -module.exports = mongoose.model('PluginTemp', pluginSchema); +const PluginModel = () => model("Plugin", pluginSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Plugin = (models.Plugin || PluginModel()) as ReturnType< + typeof PluginModel +>; diff --git a/src/lib/models/PluginField.ts b/src/lib/models/PluginField.ts new file mode 100644 index 0000000000..b2f74905ae --- /dev/null +++ b/src/lib/models/PluginField.ts @@ -0,0 +1,37 @@ +import { Schema, model, Types, models } from "mongoose"; + +export interface Interface_PluginField { + _id: Types.ObjectId; + key: string; + value: string; + status: string; + createdAt: Date; +} + +const pluginFieldSchema = new Schema({ + key: { + type: String, + required: true, + }, + value: { + type: String, + required: true, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, + createdAt: { + type: Date, + default: Date.now, + }, +}); + +const PluginFieldModel = () => + model("PluginField", pluginFieldSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const PluginField = (models.PluginField || + PluginFieldModel()) as ReturnType; diff --git a/src/lib/models/Post.ts b/src/lib/models/Post.ts new file mode 100644 index 0000000000..70bd4197b4 --- /dev/null +++ b/src/lib/models/Post.ts @@ -0,0 +1,97 @@ +import { + Schema, + model, + PopulatedDoc, + Types, + Document, + PaginateModel, + models, +} from "mongoose"; +import mongoosePaginate from "mongoose-paginate-v2"; +import { Interface_Comment } from "./Comment"; +import { Interface_Organization } from "./Organization"; +import { Interface_User } from "./User"; + +export interface Interface_Post { + _id: Types.ObjectId; + text: string; + title: string | undefined; + status: string; + createdAt: Date; + imageUrl: string | undefined; + videoUrl: string | undefined; + creator: PopulatedDoc; + organization: PopulatedDoc; + likedBy: Array>; + comments: Array>; + likeCount: number; + commentCount: number; +} + +const postSchema = new Schema({ + text: { + type: String, + required: true, + }, + title: { + type: String, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, + createdAt: { + type: Date, + default: Date.now, + }, + imageUrl: { + type: String, + required: false, + }, + videoUrl: { + type: String, + required: false, + }, + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + organization: { + type: Schema.Types.ObjectId, + ref: "Organization", + required: true, + }, + likedBy: [ + { + type: Schema.Types.ObjectId, + ref: "User", + }, + ], + comments: [ + { + type: Schema.Types.ObjectId, + ref: "Comment", + }, + ], + likeCount: { + type: Number, + default: 0, + }, + commentCount: { + type: Number, + default: 0, + }, +}); + +postSchema.plugin(mongoosePaginate); + +const PostModel = () => + model>("Post", postSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Post = (models.Post || PostModel()) as ReturnType< + typeof PostModel +>; diff --git a/src/lib/models/Task.ts b/src/lib/models/Task.ts new file mode 100644 index 0000000000..a9c0a5a986 --- /dev/null +++ b/src/lib/models/Task.ts @@ -0,0 +1,54 @@ +import { Schema, model, PopulatedDoc, Types, Document, models } from "mongoose"; +import { Interface_Event } from "./Event"; +import { Interface_User } from "./User"; + +export interface Interface_Task { + _id: Types.ObjectId; + title: string; + description: string | undefined; + status: string; + createdAt: Date; + deadline: Date | undefined; + event: PopulatedDoc; + creator: PopulatedDoc; +} + +const taskSchema = new Schema({ + title: { + type: String, + required: true, + }, + description: { + type: String, + }, + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, + createdAt: { + type: Date, + default: Date.now, + }, + deadline: { + type: Date, + }, + event: { + type: Schema.Types.ObjectId, + ref: "Event", + required: true, + }, + creator: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, +}); + +const TaskModel = () => model("Task", taskSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const Task = (models.Task || TaskModel()) as ReturnType< + typeof TaskModel +>; diff --git a/src/lib/models/User.ts b/src/lib/models/User.ts new file mode 100644 index 0000000000..cc715883c5 --- /dev/null +++ b/src/lib/models/User.ts @@ -0,0 +1,169 @@ +import { + Schema, + model, + PopulatedDoc, + PaginateModel, + Types, + Document, + models, +} from "mongoose"; +import mongoosePaginate from "mongoose-paginate-v2"; +import validator from "validator"; +import { Interface_Event } from "./Event"; +import { Interface_MembershipRequest } from "./MembershipRequest"; +import { Interface_Organization } from "./Organization"; + +export interface Interface_User { + _id: Types.ObjectId; + image: string | undefined; + token: string | undefined; + tokenVersion: number; + firstName: string; + lastName: string; + email: string; + password: string; + appLanguageCode: string; + createdOrganizations: Array>; + createdEvents: Array>; + userType: string; + joinedOrganizations: Array>; + registeredEvents: Array>; + eventAdmin: Array>; + adminFor: Array>; + membershipRequests: Array< + PopulatedDoc + >; + organizationsBlockedBy: Array< + PopulatedDoc + >; + status: string; + organizationUserBelongsTo: + | PopulatedDoc + | undefined; + pluginCreationAllowed: boolean; + adminApproved: boolean; + createdAt: Date; +} + +const userSchema = new Schema({ + image: { + type: String, + }, + token: { + type: String, + required: false, + }, + tokenVersion: { + type: Number, + default: 0, + }, + firstName: { + type: String, + required: true, + }, + lastName: { + type: String, + required: true, + }, + email: { + type: String, + required: true, + validate: [validator.isEmail, "invalid email"], + }, + password: { + type: String, + required: true, + }, + appLanguageCode: { + type: String, + required: true, + default: "en", + }, + createdOrganizations: [ + { + type: Schema.Types.ObjectId, + ref: "Organization", + }, + ], + createdEvents: [ + { + type: Schema.Types.ObjectId, + ref: "Event", + }, + ], + userType: { + type: String, + required: true, + enum: ["USER", "ADMIN", "SUPERADMIN"], + default: "USER", + }, + joinedOrganizations: [ + { + type: Schema.Types.ObjectId, + ref: "Organization", + }, + ], + registeredEvents: [ + { + type: Schema.Types.ObjectId, + ref: "Event", + }, + ], + eventAdmin: [ + { + type: Schema.Types.ObjectId, + ref: "Event", + }, + ], + adminFor: [ + { + type: Schema.Types.ObjectId, + ref: "Organization", + }, + ], + membershipRequests: [ + { + type: Schema.Types.ObjectId, + ref: "MembershipRequest", + }, + ], + organizationsBlockedBy: [ + { + type: Schema.Types.ObjectId, + ref: "Organization", + }, + ], + status: { + type: String, + required: true, + enum: ["ACTIVE", "BLOCKED", "DELETED"], + default: "ACTIVE", + }, + organizationUserBelongsTo: { + type: Schema.Types.ObjectId, + ref: "Organization", + }, + pluginCreationAllowed: { + type: Boolean, + required: true, + default: true, + }, + adminApproved: { + type: Boolean, + default: false, + }, + createdAt: { + type: Date, + default: Date.now, + }, +}); + +userSchema.plugin(mongoosePaginate); + +const UserModel = () => + model>("User", userSchema); + +// This syntax is needed to prevent Mongoose OverwriteModelError while running tests. +export const User = (models.User || UserModel()) as ReturnType< + typeof UserModel +>; diff --git a/src/lib/models/index.ts b/src/lib/models/index.ts new file mode 100644 index 0000000000..2f274f6dce --- /dev/null +++ b/src/lib/models/index.ts @@ -0,0 +1,22 @@ +export * from "./MessageChat"; +export * from "./Comment"; +export * from "./DirectChat"; +export * from "./DirectChat"; +export * from "./DirectChatMessage"; +export * from "./Donation"; +export * from "./Event"; +export * from "./EventProject"; +export * from "./File"; +export * from "./Group"; +export * from "./GroupChat"; +export * from "./GroupChatMessage"; +export * from "./ImageHash"; +export * from "./Language"; +export * from "./MembershipRequest"; +export * from "./Message"; +export * from "./Organization"; +export * from "./Plugin"; +export * from "./PluginField"; +export * from "./Post"; +export * from "./Task"; +export * from "./User"; diff --git a/src/lib/resolvers/DirectChat/creator.ts b/src/lib/resolvers/DirectChat/creator.ts new file mode 100644 index 0000000000..7be07df857 --- /dev/null +++ b/src/lib/resolvers/DirectChat/creator.ts @@ -0,0 +1,8 @@ +import { User } from "../../models"; +import { DirectChatResolvers } from "../../../generated/graphqlCodegen"; + +export const creator: DirectChatResolvers["creator"] = async (parent) => { + return await User.findOne({ + _id: parent.creator, + }).lean(); +}; diff --git a/src/lib/resolvers/DirectChat/index.ts b/src/lib/resolvers/DirectChat/index.ts new file mode 100644 index 0000000000..45ee5e528a --- /dev/null +++ b/src/lib/resolvers/DirectChat/index.ts @@ -0,0 +1,12 @@ +import { DirectChatResolvers } from "../../../generated/graphqlCodegen"; +import { creator } from "./creator"; +import { messages } from "./messages"; +import { organization } from "./organization"; +import { users } from "./users"; + +export const DirectChat: DirectChatResolvers = { + creator, + messages, + organization, + users, +}; diff --git a/src/lib/resolvers/DirectChat/messages.ts b/src/lib/resolvers/DirectChat/messages.ts new file mode 100644 index 0000000000..2c64759490 --- /dev/null +++ b/src/lib/resolvers/DirectChat/messages.ts @@ -0,0 +1,10 @@ +import { DirectChatMessage } from "../../models"; +import { DirectChatResolvers } from "../../../generated/graphqlCodegen"; + +export const messages: DirectChatResolvers["messages"] = async (parent) => { + return await DirectChatMessage.find({ + _id: { + $in: parent.messages, + }, + }).lean(); +}; diff --git a/src/lib/resolvers/DirectChat/organization.ts b/src/lib/resolvers/DirectChat/organization.ts new file mode 100644 index 0000000000..d22aec2f49 --- /dev/null +++ b/src/lib/resolvers/DirectChat/organization.ts @@ -0,0 +1,10 @@ +import { Organization } from "../../models"; +import { DirectChatResolvers } from "../../../generated/graphqlCodegen"; + +export const organization: DirectChatResolvers["organization"] = async ( + parent +) => { + return await Organization.findOne({ + _id: parent.organization, + }).lean(); +}; diff --git a/src/lib/resolvers/DirectChat/users.ts b/src/lib/resolvers/DirectChat/users.ts new file mode 100644 index 0000000000..12a3f34551 --- /dev/null +++ b/src/lib/resolvers/DirectChat/users.ts @@ -0,0 +1,10 @@ +import { User } from "../../models"; +import { DirectChatResolvers } from "../../../generated/graphqlCodegen"; + +export const users: DirectChatResolvers["users"] = async (parent) => { + return await User.find({ + _id: { + $in: parent.users, + }, + }).lean(); +}; diff --git a/src/lib/resolvers/DirectChatMessage/directChatMessageBelongsTo.ts b/src/lib/resolvers/DirectChatMessage/directChatMessageBelongsTo.ts new file mode 100644 index 0000000000..f4da818ab4 --- /dev/null +++ b/src/lib/resolvers/DirectChatMessage/directChatMessageBelongsTo.ts @@ -0,0 +1,9 @@ +import { DirectChatMessageResolvers } from "../../../generated/graphqlCodegen"; +import { DirectChat } from "../../models"; + +export const directChatMessageBelongsTo: DirectChatMessageResolvers["directChatMessageBelongsTo"] = + async (parent) => { + return await DirectChat.findOne({ + _id: parent.directChatMessageBelongsTo, + }).lean(); + }; diff --git a/src/lib/resolvers/DirectChatMessage/index.ts b/src/lib/resolvers/DirectChatMessage/index.ts new file mode 100644 index 0000000000..8afe363d1c --- /dev/null +++ b/src/lib/resolvers/DirectChatMessage/index.ts @@ -0,0 +1,10 @@ +import { DirectChatMessageResolvers } from "../../../generated/graphqlCodegen"; +import { directChatMessageBelongsTo } from "./directChatMessageBelongsTo"; +import { receiver } from "./receiver"; +import { sender } from "./sender"; + +export const DirectChatMessage: DirectChatMessageResolvers = { + directChatMessageBelongsTo, + receiver, + sender, +}; diff --git a/src/lib/resolvers/DirectChatMessage/receiver.ts b/src/lib/resolvers/DirectChatMessage/receiver.ts new file mode 100644 index 0000000000..f178177517 --- /dev/null +++ b/src/lib/resolvers/DirectChatMessage/receiver.ts @@ -0,0 +1,10 @@ +import { DirectChatMessageResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const receiver: DirectChatMessageResolvers["receiver"] = async ( + parent +) => { + return await User.findOne({ + _id: parent.receiver, + }).lean(); +}; diff --git a/src/lib/resolvers/DirectChatMessage/sender.ts b/src/lib/resolvers/DirectChatMessage/sender.ts new file mode 100644 index 0000000000..9b7b2b56c4 --- /dev/null +++ b/src/lib/resolvers/DirectChatMessage/sender.ts @@ -0,0 +1,8 @@ +import { DirectChatMessageResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const sender: DirectChatMessageResolvers["sender"] = async (parent) => { + return await User.findOne({ + _id: parent.sender, + }).lean(); +}; diff --git a/src/lib/resolvers/GroupChat/creator.ts b/src/lib/resolvers/GroupChat/creator.ts new file mode 100644 index 0000000000..396067789e --- /dev/null +++ b/src/lib/resolvers/GroupChat/creator.ts @@ -0,0 +1,8 @@ +import { GroupChatResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const creator: GroupChatResolvers["creator"] = async (parent) => { + return await User.findOne({ + _id: parent.creator, + }).lean(); +}; diff --git a/src/lib/resolvers/GroupChat/index.ts b/src/lib/resolvers/GroupChat/index.ts new file mode 100644 index 0000000000..a6a7768eeb --- /dev/null +++ b/src/lib/resolvers/GroupChat/index.ts @@ -0,0 +1,12 @@ +import { GroupChatResolvers } from "../../../generated/graphqlCodegen"; +import { creator } from "./creator"; +import { messages } from "./messages"; +import { organization } from "./organization"; +import { users } from "./users"; + +export const GroupChat: GroupChatResolvers = { + creator, + messages, + organization, + users, +}; diff --git a/src/lib/resolvers/GroupChat/messages.ts b/src/lib/resolvers/GroupChat/messages.ts new file mode 100644 index 0000000000..18d851661c --- /dev/null +++ b/src/lib/resolvers/GroupChat/messages.ts @@ -0,0 +1,10 @@ +import { GroupChatResolvers } from "../../../generated/graphqlCodegen"; +import { GroupChatMessage } from "../../models"; + +export const messages: GroupChatResolvers["messages"] = async (parent) => { + return await GroupChatMessage.find({ + _id: { + $in: parent.messages, + }, + }).lean(); +}; diff --git a/src/lib/resolvers/GroupChat/organization.ts b/src/lib/resolvers/GroupChat/organization.ts new file mode 100644 index 0000000000..fdf2830046 --- /dev/null +++ b/src/lib/resolvers/GroupChat/organization.ts @@ -0,0 +1,10 @@ +import { GroupChatResolvers } from "../../../generated/graphqlCodegen"; +import { Organization } from "../../models"; + +export const organization: GroupChatResolvers["organization"] = async ( + parent +) => { + return await Organization.findOne({ + _id: parent.organization, + }).lean(); +}; diff --git a/src/lib/resolvers/GroupChat/users.ts b/src/lib/resolvers/GroupChat/users.ts new file mode 100644 index 0000000000..a70e7c108e --- /dev/null +++ b/src/lib/resolvers/GroupChat/users.ts @@ -0,0 +1,10 @@ +import { GroupChatResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const users: GroupChatResolvers["users"] = async (parent) => { + return await User.find({ + _id: { + $in: parent.users, + }, + }).lean(); +}; diff --git a/src/lib/resolvers/GroupChatMessage/groupChatMessageBelongsTo.ts b/src/lib/resolvers/GroupChatMessage/groupChatMessageBelongsTo.ts new file mode 100644 index 0000000000..7d21135359 --- /dev/null +++ b/src/lib/resolvers/GroupChatMessage/groupChatMessageBelongsTo.ts @@ -0,0 +1,9 @@ +import { GroupChatMessageResolvers } from "../../../generated/graphqlCodegen"; +import { GroupChat } from "../../models"; + +export const groupChatMessageBelongsTo: GroupChatMessageResolvers["groupChatMessageBelongsTo"] = + async (parent) => { + return await GroupChat.findOne({ + _id: parent.groupChatMessageBelongsTo, + }).lean(); + }; diff --git a/src/lib/resolvers/GroupChatMessage/index.ts b/src/lib/resolvers/GroupChatMessage/index.ts new file mode 100644 index 0000000000..005feac299 --- /dev/null +++ b/src/lib/resolvers/GroupChatMessage/index.ts @@ -0,0 +1,8 @@ +import { GroupChatMessageResolvers } from "../../../generated/graphqlCodegen"; +import { groupChatMessageBelongsTo } from "./groupChatMessageBelongsTo"; +import { sender } from "./sender"; + +export const GroupChatMessage: GroupChatMessageResolvers = { + groupChatMessageBelongsTo, + sender, +}; diff --git a/src/lib/resolvers/GroupChatMessage/sender.ts b/src/lib/resolvers/GroupChatMessage/sender.ts new file mode 100644 index 0000000000..0ff8e3691a --- /dev/null +++ b/src/lib/resolvers/GroupChatMessage/sender.ts @@ -0,0 +1,8 @@ +import { GroupChatMessageResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const sender: GroupChatMessageResolvers["sender"] = async (parent) => { + return await User.findOne({ + _id: parent.sender, + }).lean(); +}; diff --git a/src/lib/resolvers/MembershipRequest/index.ts b/src/lib/resolvers/MembershipRequest/index.ts new file mode 100644 index 0000000000..1d7546b43d --- /dev/null +++ b/src/lib/resolvers/MembershipRequest/index.ts @@ -0,0 +1,8 @@ +import { MembershipRequestResolvers } from "../../../generated/graphqlCodegen"; +import { organization } from "./organization"; +import { user } from "./user"; + +export const MembershipRequest: MembershipRequestResolvers = { + organization, + user, +}; diff --git a/src/lib/resolvers/MembershipRequest/organization.ts b/src/lib/resolvers/MembershipRequest/organization.ts new file mode 100644 index 0000000000..f74d789577 --- /dev/null +++ b/src/lib/resolvers/MembershipRequest/organization.ts @@ -0,0 +1,10 @@ +import { MembershipRequestResolvers } from "../../../generated/graphqlCodegen"; +import { Organization } from "../../models"; + +export const organization: MembershipRequestResolvers["organization"] = async ( + parent +) => { + return Organization.findOne({ + _id: parent.organization, + }).lean(); +}; diff --git a/src/lib/resolvers/MembershipRequest/user.ts b/src/lib/resolvers/MembershipRequest/user.ts new file mode 100644 index 0000000000..bedb7f65a8 --- /dev/null +++ b/src/lib/resolvers/MembershipRequest/user.ts @@ -0,0 +1,8 @@ +import { MembershipRequestResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const user: MembershipRequestResolvers["user"] = async (parent) => { + return await User.findOne({ + _id: parent.user, + }).lean(); +}; diff --git a/src/lib/resolvers/Mutation/acceptAdmin.ts b/src/lib/resolvers/Mutation/acceptAdmin.ts new file mode 100644 index 0000000000..350fff79f6 --- /dev/null +++ b/src/lib/resolvers/Mutation/acceptAdmin.ts @@ -0,0 +1,62 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; + +export const acceptAdmin: MutationResolvers["acceptAdmin"] = async ( + _parent, + args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + if (currentUser.userType !== "SUPERADMIN") { + throw new Error(USER_NOT_AUTHORIZED); + } + + const userExists = await User.exists({ + _id: args.id, + }); + + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + await User.updateOne( + { + _id: args.id, + }, + { + $set: { + adminApproved: true, + }, + } + ); + + return true; +}; diff --git a/src/lib/resolvers/Mutation/acceptMembershipRequest.ts b/src/lib/resolvers/Mutation/acceptMembershipRequest.ts new file mode 100644 index 0000000000..1c04e9a503 --- /dev/null +++ b/src/lib/resolvers/Mutation/acceptMembershipRequest.ts @@ -0,0 +1,138 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck } from "../../utilities"; +import { MembershipRequest, Organization, User } from "../../models"; +import { + MEMBERSHIP_REQUEST_NOT_FOUND, + MEMBERSHIP_REQUEST_NOT_FOUND_CODE, + MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE, + MEMBERSHIP_REQUEST_NOT_FOUND_PARAM, + USER_ALREADY_MEMBER, + USER_ALREADY_MEMBER_CODE, + USER_ALREADY_MEMBER_MESSAGE, + USER_ALREADY_MEMBER_PARAM, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + USER_NOT_FOUND, +} from "../../../constants"; + +export const acceptMembershipRequest: MutationResolvers["acceptMembershipRequest"] = + async (_parent, args, context) => { + const membershipRequest = await MembershipRequest.findOne({ + _id: args.membershipRequestId, + }).lean(); + + // Checks whether membershipRequest exists. + if (!membershipRequest) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? MEMBERSHIP_REQUEST_NOT_FOUND + : requestContext.translate(MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE), + MEMBERSHIP_REQUEST_NOT_FOUND_CODE, + MEMBERSHIP_REQUEST_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: membershipRequest.organization, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const user = await User.findOne({ + _id: membershipRequest.user, + }).lean(); + + // Checks whether user exists. + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization. + adminCheck(context.userId, organization); + + const userIsOrganizationMember = organization.members.some( + (member) => member.toString() === user?._id.toString() + ); + + // Checks whether user is already a member of organization. + if (userIsOrganizationMember === true) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? USER_ALREADY_MEMBER + : requestContext.translate(USER_ALREADY_MEMBER_MESSAGE), + USER_ALREADY_MEMBER_CODE, + USER_ALREADY_MEMBER_PARAM + ); + } + + // Delete the membershipRequest. + await MembershipRequest.deleteOne({ + _id: membershipRequest._id, + }); + + /* + Add user._id to members list and remove membershipRequest._id + from membershipRequests list on organization's document. + */ + await Organization.updateOne( + { + _id: organization._id, + }, + { + $push: { + members: user._id, + }, + + $set: { + membershipRequests: organization.membershipRequests.filter( + (request) => request.toString() !== membershipRequest._id.toString() + ), + }, + } + ); + + /* + Add organization._id to joinedOrganizations list and remove + membershipRequest._id from membershipRequests list on user's document. + */ + await User.updateOne( + { + _id: user._id, + }, + { + $push: { + joinedOrganizations: organization._id, + }, + + $set: { + membershipRequests: user.membershipRequests.filter( + (request) => request.toString() !== membershipRequest._id.toString() + ), + }, + } + ); + + return membershipRequest; + }; diff --git a/src/lib/resolvers/Mutation/addLanguageTranslation.ts b/src/lib/resolvers/Mutation/addLanguageTranslation.ts new file mode 100644 index 0000000000..6df7e7380d --- /dev/null +++ b/src/lib/resolvers/Mutation/addLanguageTranslation.ts @@ -0,0 +1,58 @@ +import { IN_PRODUCTION } from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { Language } from "../../models"; + +export const addLanguageTranslation: MutationResolvers["addLanguageTranslation"] = + async (_parent, args) => { + const language = await Language.findOne({ + en: args.data.en_value, + }).lean(); + + // Checks if language exists. + if (language) { + language.translation.forEach((element) => { + // Checks whether the translation already exists. + if (element.lang_code === args.data.translation_lang_code) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? "Translation already present" + : requestContext.translate("translation.alreadyPresent"), + "translation.alreadyPresent", + "translationAlreadyPresent" + ); + } + }); + + // Updates language with new translation and returns the updated language. + return await Language.findOneAndUpdate( + { + en: args.data.en_value, + }, + { + $push: { + translation: { + lang_code: args.data.translation_lang_code, + value: args.data.translation_value, + }, + }, + }, + { + new: true, + } + ).lean(); + } + + // Creates new language. + const createdLanguage = await Language.create({ + en: args.data.en_value, + translation: [ + { + lang_code: args.data.translation_lang_code, + value: args.data.translation_value, + }, + ], + }); + + return createdLanguage.toObject(); + }; diff --git a/src/lib/resolvers/Mutation/addOrganizationImage.ts b/src/lib/resolvers/Mutation/addOrganizationImage.ts new file mode 100644 index 0000000000..a40a982494 --- /dev/null +++ b/src/lib/resolvers/Mutation/addOrganizationImage.ts @@ -0,0 +1,71 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck, uploadImage } from "../../utilities"; +import { User, Organization } from "../../models"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const addOrganizationImage: MutationResolvers["addOrganizationImage"] = + async (_parent, args, context) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization. + adminCheck(context.userId, organization); + + // Upload Image + const uploadImageObj = await uploadImage(args.file, organization.image!); + + // Updates the organization with new image and returns the updated organization. + return await Organization.findOneAndUpdate( + { + _id: organization._id, + }, + { + $set: { + image: uploadImageObj.imageAlreadyInDbPath + ? uploadImageObj.imageAlreadyInDbPath + : uploadImageObj.newImagePath, + }, + }, + { + new: true, + } + ).lean(); + }; diff --git a/src/lib/resolvers/Mutation/addUserImage.ts b/src/lib/resolvers/Mutation/addUserImage.ts new file mode 100644 index 0000000000..de73c41279 --- /dev/null +++ b/src/lib/resolvers/Mutation/addUserImage.ts @@ -0,0 +1,51 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { uploadImage } from "../../utilities"; +import { User } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const addUserImage: MutationResolvers["addUserImage"] = async ( + _parent, + args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const imageToUpload = await uploadImage(args.file, currentUser.image!); + + // Updates the user with new image and returns the updated user. + return await User.findOneAndUpdate( + { + _id: currentUser._id, + }, + { + $set: { + image: imageToUpload.imageAlreadyInDbPath + ? imageToUpload.imageAlreadyInDbPath + : imageToUpload.newImagePath, + }, + }, + { + new: true, + } + ).lean(); +}; diff --git a/src/lib/resolvers/Mutation/addUserToGroupChat.ts b/src/lib/resolvers/Mutation/addUserToGroupChat.ts new file mode 100644 index 0000000000..3dee73f102 --- /dev/null +++ b/src/lib/resolvers/Mutation/addUserToGroupChat.ts @@ -0,0 +1,104 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck } from "../../utilities"; +import { User, GroupChat, Organization } from "../../models"; +import { + IN_PRODUCTION, + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_MESSAGE, + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM, + USER_ALREADY_MEMBER, + USER_ALREADY_MEMBER_CODE, + USER_ALREADY_MEMBER_MESSAGE, + USER_ALREADY_MEMBER_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const addUserToGroupChat: MutationResolvers["addUserToGroupChat"] = + async (_parent, args, context) => { + const groupChat = await GroupChat.findOne({ + _id: args.chatId, + }).lean(); + + // Checks whether groupChat exists. + if (!groupChat) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: groupChat.organization, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization. + adminCheck(context.userId, organization); + + const userExists = await User.exists({ + _id: args.userId, + }); + + // Checks whether user with _id === args.userId exists. + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const isUserGroupChatMember = groupChat.users.some( + (user) => user.toString() === args.userId.toString() + ); + + // Checks whether user with _id === args.userId is already a member of groupChat. + if (isUserGroupChatMember === true) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? USER_ALREADY_MEMBER + : requestContext.translate(USER_ALREADY_MEMBER_MESSAGE), + USER_ALREADY_MEMBER_CODE, + USER_ALREADY_MEMBER_PARAM + ); + } + + // Adds args.userId to users list on groupChat's document and returns the updated groupChat. + return await GroupChat.findOneAndUpdate( + { + _id: args.chatId, + }, + { + $push: { + users: args.userId, + }, + }, + { + new: true, + } + ).lean(); + }; diff --git a/src/lib/resolvers/Mutation/adminRemoveEvent.ts b/src/lib/resolvers/Mutation/adminRemoveEvent.ts new file mode 100644 index 0000000000..f4bc87ad62 --- /dev/null +++ b/src/lib/resolvers/Mutation/adminRemoveEvent.ts @@ -0,0 +1,105 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck } from "../../utilities"; +import { User, Organization, Event } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_PARAM, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_MESSAGE, +} from "../../../constants"; + +export const adminRemoveEvent: MutationResolvers["adminRemoveEvent"] = async ( + _parent, + args, + context +) => { + const event = await Event.findOne({ + _id: args.eventId, + }).lean(); + + // Checks whether event exists. + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: event.organization, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser is an admin of organization. + adminCheck(currentUser._id, organization); + + /* + Removes event._id from eventAdmin, createdEvents and registeredEvents lists on + currentUser document. + */ + await User.updateOne( + { + _id: currentUser._id, + }, + { + $set: { + eventAdmin: currentUser.eventAdmin.filter( + (adminForEvent) => adminForEvent.toString() !== event?._id.toString() + ), + createdEvents: currentUser.createdEvents.filter( + (createdEvent) => createdEvent.toString() !== event?._id.toString() + ), + registeredEvents: currentUser.registeredEvents.filter( + (registeredEvent) => + registeredEvent.toString() !== event?._id.toString() + ), + }, + } + ); + + // Deletes the event. + await Event.deleteOne({ + _id: event._id, + }); + + // Returns the deleted event. + return event; +}; diff --git a/src/lib/resolvers/Mutation/adminRemoveGroup.ts b/src/lib/resolvers/Mutation/adminRemoveGroup.ts new file mode 100644 index 0000000000..caa96ee7fd --- /dev/null +++ b/src/lib/resolvers/Mutation/adminRemoveGroup.ts @@ -0,0 +1,96 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck } from "../../utilities"; +import { User, Organization, GroupChat } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_PARAM, + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_MESSAGE, +} from "../../../constants"; + +// @ts-ignore +export const adminRemoveGroup: MutationResolvers["adminRemoveGroup"] = async ( + _parent, + args, + context +) => { + const groupChat = await GroupChat.findOne({ + _id: args.groupId, + }).lean(); + + // Checks whether groupChat exists. + if (!groupChat) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: groupChat.organization, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization. + adminCheck(context.userId, organization); + + //remove message from organization + // org.overwrite({ + // ...org._doc, + // messages: org._doc.posts.filter((message) => message != args.messageId), + // }); + // await org.save(); + + // //remove post from user + // user.overwrite({ + // ...user._doc, + // messages: user._doc.posts.filter((message) => message != args.messageId), + // }); + // await user.save(); + + // Deletes the groupChat. + await GroupChat.deleteOne({ + _id: groupChat._id, + }); + + // Returns the deleted groupChat. + return groupChat; +}; diff --git a/src/lib/resolvers/Mutation/adminRemovePost.ts b/src/lib/resolvers/Mutation/adminRemovePost.ts new file mode 100644 index 0000000000..26d0525e5e --- /dev/null +++ b/src/lib/resolvers/Mutation/adminRemovePost.ts @@ -0,0 +1,103 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck } from "../../utilities"; +import { User, Organization, Post } from "../../models"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + POST_NOT_FOUND, + POST_NOT_FOUND_MESSAGE, + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const adminRemovePost: MutationResolvers["adminRemovePost"] = async ( + _parent, + args, + context +) => { + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization. + adminCheck(context.userId, organization); + + const post = await Post.findOne({ + _id: args.postId, + }).lean(); + + // Checks whether post exists. + if (!post) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? POST_NOT_FOUND + : requestContext.translate(POST_NOT_FOUND_MESSAGE), + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_PARAM + ); + } + + // Removes post._id from posts list on organization document. + await Organization.updateOne( + { + _id: organization._id, + }, + { + $set: { + posts: organization.posts.filter( + (organizationPost) => + organizationPost.toString() !== post?._id.toString() + ), + }, + } + ); + + // //remove post from user + // user.overwrite({ + // ...user._doc, + // posts: user._doc.posts.filter((post) => post != args.postId), + // }); + // await user.save(); + + // Deletes the post. + await Post.deleteOne({ + _id: args.postId, + }); + + // Returns the deleted post. + return post; +}; diff --git a/src/lib/resolvers/Mutation/blockPluginCreationBySuperadmin.ts b/src/lib/resolvers/Mutation/blockPluginCreationBySuperadmin.ts new file mode 100644 index 0000000000..391ae40318 --- /dev/null +++ b/src/lib/resolvers/Mutation/blockPluginCreationBySuperadmin.ts @@ -0,0 +1,78 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; + +export const blockPluginCreationBySuperadmin: MutationResolvers["blockPluginCreationBySuperadmin"] = + async (_parent, args, context) => { + const userExists = await User.exists({ + _id: args.userId, + }); + + // Checks whether user with _id === args.userId exists. + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser is a SUPERADMIN. + const currentUserIsSuperAdmin = currentUser.userType === "SUPERADMIN"; + + if (currentUserIsSuperAdmin === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + /* + Sets pluginCreationAllowed field on document of user with _id === args.userId + to !args.blockUser and returns the updated user. + */ + return await User.findOneAndUpdate( + { + _id: args.userId, + }, + { + $set: { + pluginCreationAllowed: !args.blockUser, + }, + }, + { + new: true, + } + ).lean(); + }; diff --git a/src/lib/resolvers/Mutation/blockUser.ts b/src/lib/resolvers/Mutation/blockUser.ts new file mode 100644 index 0000000000..6e642c9f18 --- /dev/null +++ b/src/lib/resolvers/Mutation/blockUser.ts @@ -0,0 +1,105 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck } from "../../utilities"; +import { + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { Organization, User } from "../../models"; + +export const blockUser: MutationResolvers["blockUser"] = async ( + _parent, + args, + context +) => { + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const userExists = await User.exists({ + _id: args.userId, + }); + + // Checks whether user with _id === args.userId exists. + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization. + adminCheck(context.userId, organization); + + const userIsBlocked = organization.blockedUsers.some( + (blockedUser) => blockedUser.toString() === args.userId.toString() + ); + + // Checks whether user with _id === args.userId is already blocked from organization. + if (userIsBlocked === true) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // Adds args.userId to blockedUsers list on organization's document. + await Organization.updateOne( + { + _id: organization._id, + }, + { + $push: { + blockedUsers: args.userId, + }, + } + ); + + /* + Adds organization._id to organizationsBlockedBy list on user's document + with _id === args.userId and returns the updated user. + */ + return await User.findOneAndUpdate( + { + _id: args.userId, + }, + { + $push: { + organizationsBlockedBy: organization._id, + }, + }, + { + new: true, + } + ) + .select(["-password"]) + .lean(); +}; diff --git a/src/lib/resolvers/Mutation/cancelMembershipRequest.ts b/src/lib/resolvers/Mutation/cancelMembershipRequest.ts new file mode 100644 index 0000000000..b872d889f2 --- /dev/null +++ b/src/lib/resolvers/Mutation/cancelMembershipRequest.ts @@ -0,0 +1,120 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Organization, MembershipRequest } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + USER_NOT_FOUND, + USER_NOT_AUTHORIZED, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, + MEMBERSHIP_REQUEST_NOT_FOUND, + MEMBERSHIP_REQUEST_NOT_FOUND_CODE, + MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE, + MEMBERSHIP_REQUEST_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const cancelMembershipRequest: MutationResolvers["cancelMembershipRequest"] = + async (_parent, args, context) => { + const membershipRequest = await MembershipRequest.findOne({ + _id: args.membershipRequestId, + }).lean(); + + // Checks whether membershipRequest exists. + if (!membershipRequest) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? MEMBERSHIP_REQUEST_NOT_FOUND + : requestContext.translate(MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE), + MEMBERSHIP_REQUEST_NOT_FOUND_CODE, + MEMBERSHIP_REQUEST_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: membershipRequest.organization, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const currentUserCreatedMembershipRequest = + currentUser._id.toString() === membershipRequest.user.toString(); + + // Checks whether currentUser is the creator of membershipRequest. + if (currentUserCreatedMembershipRequest === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // Deletes the membershipRequest. + await MembershipRequest.deleteOne({ + _id: membershipRequest._id, + }); + + // Removes membershipRequest._id from membershipRequests list on organization's document. + await Organization.updateOne( + { + _id: organization._id, + }, + { + $set: { + membershipRequests: organization.membershipRequests.filter( + (request) => request.toString() !== membershipRequest._id.toString() + ), + }, + } + ); + + // Removes membershipRequest._id from membershipRequests list on currentUser's document. + await User.updateOne( + { + _id: currentUser._id, + }, + { + $set: { + membershipRequests: currentUser.membershipRequests.filter( + (request) => request.toString() !== membershipRequest._id.toString() + ), + }, + } + ); + + // Returns the deleted membershipRequest. + return membershipRequest; + }; diff --git a/src/lib/resolvers/Mutation/createAdmin.ts b/src/lib/resolvers/Mutation/createAdmin.ts new file mode 100644 index 0000000000..f319628456 --- /dev/null +++ b/src/lib/resolvers/Mutation/createAdmin.ts @@ -0,0 +1,124 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Organization } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { creatorCheck } from "../../utilities"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + USER_NOT_FOUND, + USER_NOT_AUTHORIZED, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_MEMBER_NOT_FOUND, + ORGANIZATION_MEMBER_NOT_FOUND_CODE, + ORGANIZATION_MEMBER_NOT_FOUND_MESSAGE, + ORGANIZATION_MEMBER_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; + +export const createAdmin: MutationResolvers["createAdmin"] = async ( + _parent, + args, + context +) => { + const organization = await Organization.findOne({ + _id: args.data.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is the creator of organization. + creatorCheck(context.userId, organization); + + const userExists = await User.exists({ + _id: args.data.userId, + }); + + // Checks whether user with _id === args.data.userId exists. + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const userIsOrganizationMember = organization.members.some( + (member) => member.toString() === args.data.userId.toString() + ); + + // Checks whether user with _id === args.data.userId is not a member of organization. + if (userIsOrganizationMember === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_MEMBER_NOT_FOUND + : requestContext.translate(ORGANIZATION_MEMBER_NOT_FOUND_MESSAGE), + ORGANIZATION_MEMBER_NOT_FOUND_CODE, + ORGANIZATION_MEMBER_NOT_FOUND_PARAM + ); + } + + const userIsOrganizationAdmin = organization.admins.some( + (admin) => admin.toString() === args.data.userId.toString() + ); + + // Checks whether user with _id === args.data.userId is already an admin of organization. + if (userIsOrganizationAdmin === true) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // Adds args.data.userId to admins list of organization's document. + await Organization.updateOne( + { + _id: organization._id, + }, + { + $push: { + admins: args.data.userId, + }, + } + ); + + /* + Adds organization._id to adminFor list on user's document with _id === args.data.userId + and returns the updated user. + */ + return await User.findOneAndUpdate( + { + _id: args.data.userId, + }, + { + $push: { + adminFor: organization._id, + }, + }, + { + new: true, + } + ) + .select(["-password"]) + .lean(); +}; diff --git a/src/lib/resolvers/Mutation/createComment.ts b/src/lib/resolvers/Mutation/createComment.ts new file mode 100644 index 0000000000..82af19f6c4 --- /dev/null +++ b/src/lib/resolvers/Mutation/createComment.ts @@ -0,0 +1,59 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Post, Comment } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createComment: MutationResolvers["createComment"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Creates new comment. + const createdComment = await Comment.create({ + ...args.data, + creator: context.userId, + post: args.postId, + }); + + /* + Adds createdComment._id to comments list and increases commentCount by 1 + on post's document with _id === args.postId. + */ + await Post.updateOne( + { + _id: args.postId, + }, + { + $push: { + comments: createdComment._id, + }, + $inc: { + commentCount: 1, + }, + } + ); + + // Returns the createdComment. + return createdComment.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createDirectChat.ts b/src/lib/resolvers/Mutation/createDirectChat.ts new file mode 100644 index 0000000000..0e72243905 --- /dev/null +++ b/src/lib/resolvers/Mutation/createDirectChat.ts @@ -0,0 +1,83 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Organization, DirectChat } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createDirectChat: MutationResolvers["createDirectChat"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organizationExists = await Organization.exists({ + _id: args.data?.organizationId, + }); + + // Checks whether organization with _id === args.data.organizationId exists. + if (organizationExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Variable to store list of users to be members of directChat. + const usersInDirectChat = []; + + // Loops over each item in args.data.userIds list. + for await (const userId of args.data!.userIds) { + const userExists = await User.exists({ + _id: userId, + }); + + // Checks whether user with _id === userId exists. + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + usersInDirectChat.push(userId); + } + + // Creates new directChat. + const createdDirectChat = await DirectChat.create({ + creator: context.userId, + users: usersInDirectChat, + organization: args.data?.organizationId, + }); + + // Returns createdDirectChat. + return createdDirectChat.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createDonation.ts b/src/lib/resolvers/Mutation/createDonation.ts new file mode 100644 index 0000000000..c02d105a51 --- /dev/null +++ b/src/lib/resolvers/Mutation/createDonation.ts @@ -0,0 +1,24 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { Donation } from "../../models"; + +/** + * @name createDonation creates a Donation as transaction and returns the same + * @description creates a document of Donation type and stores it in database + * @param {any} parent parent of current request + * @param {object} args payload provided with the request + */ +export const createDonation: MutationResolvers["createDonation"] = async ( + _parent, + args +) => { + const createdDonation = await Donation.create({ + amount: args.amount, + nameOfOrg: args.nameOfOrg, + nameOfUser: args.nameOfUser, + orgId: args.orgId, + payPalId: args.payPalId, + userId: args.userId, + }); + + return createdDonation.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createEvent.ts b/src/lib/resolvers/Mutation/createEvent.ts new file mode 100644 index 0000000000..a706825627 --- /dev/null +++ b/src/lib/resolvers/Mutation/createEvent.ts @@ -0,0 +1,131 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Organization, Event } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + ORGANIZATION_NOT_AUTHORIZED, + ORGANIZATION_NOT_AUTHORIZED_MESSAGE, + ORGANIZATION_NOT_AUTHORIZED_CODE, + ORGANIZATION_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; +import admin, { credential } from "firebase-admin"; + +const applicationDefault = credential.applicationDefault; + +admin.initializeApp({ credential: applicationDefault() }); + +export const createEvent: MutationResolvers["createEvent"] = async ( + _parent, + args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: args.data!.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const userCreatedOrganization = currentUser.createdOrganizations.some( + (createdOrganization) => + createdOrganization.toString() === organization._id.toString() + ); + + const userJoinedOrganization = currentUser.joinedOrganizations.some( + (joinedOrganization) => + joinedOrganization.toString() === organization._id.toString() + ); + + // Checks whether currentUser neither created nor joined the organization. + if (!(userCreatedOrganization || userJoinedOrganization)) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_AUTHORIZED + : requestContext.translate(ORGANIZATION_NOT_AUTHORIZED_MESSAGE), + ORGANIZATION_NOT_AUTHORIZED_CODE, + ORGANIZATION_NOT_AUTHORIZED_PARAM + ); + } + + // Creates new event. + const createdEvent = await Event.create({ + ...args.data, + creator: currentUser._id, + registrants: [ + { + userId: currentUser._id.toString(), + user: currentUser._id, + }, + ], + admins: [currentUser._id], + organization: organization._id, + }); + + /* + Adds createdEvent._id to eventAdmin, createdEvents and registeredEvents lists + on currentUser's document. + */ + await User.updateOne( + { + _id: currentUser._id, + }, + { + $push: { + eventAdmin: createdEvent._id, + createdEvents: createdEvent._id, + registeredEvents: createdEvent._id, + }, + } + ); + + for (let i = 0; i < organization.members.length; i++) { + const user = await User.findOne({ + _id: organization.members[i], + }).lean(); + + // Checks whether both user and user.token exist. + if (user && user.token) { + await admin.messaging().send({ + token: user.token, + notification: { + title: "New Event", + body: `${currentUser.firstName} has created a new event in ${organization.name}`, + }, + }); + } + } + + // Returns the createdEvent. + return createdEvent.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createEventProject.ts b/src/lib/resolvers/Mutation/createEventProject.ts new file mode 100644 index 0000000000..0515555066 --- /dev/null +++ b/src/lib/resolvers/Mutation/createEventProject.ts @@ -0,0 +1,79 @@ +import { User, EventProject, Event } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createEventProject = async ( + _parent: any, + args: any, + context: any +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const event = await Event.findOne({ + _id: args.data.eventId, + }).lean(); + + // Checks whether event exists. + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + const currentUserIsEventAdmin = event.admins.some( + (admin) => admin.toString() === context.userId.toString() + ); + + // Checks whether currentUser with _id === context.userId is an admin of event. + if (currentUserIsEventAdmin === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // Creates new eventProject. + const createdEventProject = await EventProject.create({ + title: args.data.title, + description: args.data.description, + event: args.data.eventId, + creator: context.userId, + }); + + // Returns createdEventProject. + return createdEventProject.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createGroupChat.ts b/src/lib/resolvers/Mutation/createGroupChat.ts new file mode 100644 index 0000000000..0b223c0aa8 --- /dev/null +++ b/src/lib/resolvers/Mutation/createGroupChat.ts @@ -0,0 +1,84 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, GroupChat, Organization } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createGroupChat: MutationResolvers["createGroupChat"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organizationExists = await Organization.exists({ + _id: args.data?.organizationId, + }); + + // Checks whether organization with _id === args.data.organizationId exists. + if (organizationExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Variable to store list of users to be members of groupChat. + const usersInGroupChat = []; + + // Loops over each item in args.data.userIds list. + for await (const userId of args.data!.userIds) { + const userExists = await User.exists({ + _id: userId, + }); + + // Checks whether user with _id === userId exists. + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + usersInGroupChat.push(userId); + } + + // Creates new groupChat. + const createdGroupChat = await GroupChat.create({ + creator: context.userId, + users: usersInGroupChat, + organization: args.data?.organizationId, + title: args.data?.title, + }); + + // Returns createdGroupChat. + return createdGroupChat.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createMessageChat.ts b/src/lib/resolvers/Mutation/createMessageChat.ts new file mode 100644 index 0000000000..1b403877e7 --- /dev/null +++ b/src/lib/resolvers/Mutation/createMessageChat.ts @@ -0,0 +1,56 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, MessageChat } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createMessageChat: MutationResolvers["createMessageChat"] = async ( + _parent, + args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + const receiverUser = await User.findOne({ + _id: args.data.receiver, + }).lean(); + + // Checks whether receiverUser exists. + if (!receiverUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Boolean to identify whether both sender and receiver for messageChat have the same appLanguageCode. + const isSenderReceiverLanguageSame = + receiverUser?.appLanguageCode === currentUser?.appLanguageCode; + + // Creates new messageChat. + const createdMessageChat = await MessageChat.create({ + sender: currentUser?._id, + receiver: receiverUser._id, + message: args.data.message, + languageBarrier: !isSenderReceiverLanguageSame, + }); + + context.pubsub.publish("CHAT_CHANNEL", { + directMessageChat: { + ...createdMessageChat, + }, + }); + + // Returns createdMessageChat. + return createdMessageChat.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createOrganization.ts b/src/lib/resolvers/Mutation/createOrganization.ts new file mode 100644 index 0000000000..a3730165e2 --- /dev/null +++ b/src/lib/resolvers/Mutation/createOrganization.ts @@ -0,0 +1,68 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Organization } from "../../models"; +import { uploadImage } from "../../utilities"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createOrganization: MutationResolvers["createOrganization"] = + async (_parent, args, context) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + //Upload file + let uploadImageObj; + if (args.file) { + uploadImageObj = await uploadImage(args.file, null); + } + + // Creates new organization. + const createdOrganization = await Organization.create({ + ...args.data, + image: uploadImageObj + ? uploadImageObj.imageAlreadyInDbPath + ? uploadImageObj.imageAlreadyInDbPath + : uploadImageObj.newImagePath + : null, + creator: context.userId, + admins: [context.userId], + members: [context.userId], + }); + + /* + Adds createdOrganization._id to joinedOrganizations, createdOrganizations + and adminFor lists on currentUser's document with _id === context.userId + */ + await User.updateOne( + { + _id: context.userId, + }, + { + $push: { + joinedOrganizations: createdOrganization._id, + createdOrganizations: createdOrganization._id, + adminFor: createdOrganization._id, + }, + } + ); + + // Returns createdOrganization. + return createdOrganization.toObject(); + }; diff --git a/src/lib/resolvers/Mutation/createPlugin.ts b/src/lib/resolvers/Mutation/createPlugin.ts new file mode 100644 index 0000000000..7d657cb24c --- /dev/null +++ b/src/lib/resolvers/Mutation/createPlugin.ts @@ -0,0 +1,24 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { Plugin } from "../../models"; + +/** + * @name createPlugin creates a Plugin and return the same + * @description creates a document of Plugin type and stores it in database + * @param {any} parent parent of current request + * @param {object} args payload provided with the request + * @param {any} context context of entire application + */ + +export const createPlugin: MutationResolvers["createPlugin"] = async ( + _parent, + args, + _context +) => { + // Creates new plugin. + const createdPlugin = await Plugin.create({ + ...args, + }); + + // Returns createdPlugin. + return createdPlugin.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createPost.ts b/src/lib/resolvers/Mutation/createPost.ts new file mode 100644 index 0000000000..ae3dde33f4 --- /dev/null +++ b/src/lib/resolvers/Mutation/createPost.ts @@ -0,0 +1,68 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Post, Organization } from "../../models"; +import { uploadImage } from "../../utilities"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createPost: MutationResolvers["createPost"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id == context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organizationExists = await Organization.exists({ + _id: args.data.organizationId, + }); + + // Checks whether organization with _id == args.data.organizationId exists. + if (organizationExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + let uploadImageObj; + + if (args.file) { + uploadImageObj = await uploadImage(args.file, ""); + } + + // Creates new post. + const createdPost = await Post.create({ + ...args.data, + creator: context.userId, + organization: args.data.organizationId, + imageUrl: args.file ? uploadImageObj?.newImagePath : "", + }); + + // Returns createdPost. + return createdPost.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/createTask.ts b/src/lib/resolvers/Mutation/createTask.ts new file mode 100644 index 0000000000..20bcd3d9b8 --- /dev/null +++ b/src/lib/resolvers/Mutation/createTask.ts @@ -0,0 +1,72 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Task, Event } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const createTask: MutationResolvers["createTask"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id == context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const eventExists = await Event.exists({ + _id: args.eventId, + }); + + // Checks whether event with _id == args.eventId exists. + if (eventExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + // Creates new task. + const createdTask = await Task.create({ + ...args.data, + event: args.eventId, + creator: context.userId, + }); + + // Adds createdTask._id to tasks list on event's document with _id === args.eventId. + await Event.updateOne( + { + _id: args.eventId, + }, + { + $push: { + tasks: createdTask._id, + }, + } + ); + + // Returns createdTask. + return createdTask.toObject(); +}; diff --git a/src/lib/resolvers/Mutation/deleteDonationById.ts b/src/lib/resolvers/Mutation/deleteDonationById.ts new file mode 100644 index 0000000000..7e49ad9f76 --- /dev/null +++ b/src/lib/resolvers/Mutation/deleteDonationById.ts @@ -0,0 +1,17 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { Donation } from "../../models"; + +/** + * @name deleteDonationById + * @description delets a Donation record from the database and returns it if successful. + * @param {any} parent parent of current request + * @param {object} args payload provided with the request + */ +export const deleteDonationById: MutationResolvers["deleteDonationById"] = + async (_parent, args) => { + const deletedDonation = await Donation.deleteOne({ + _id: args.id, + }); + + return { success: deletedDonation.deletedCount ? true : false }; + }; diff --git a/src/lib/resolvers/Mutation/forgotPassword.ts b/src/lib/resolvers/Mutation/forgotPassword.ts new file mode 100644 index 0000000000..7f177ce052 --- /dev/null +++ b/src/lib/resolvers/Mutation/forgotPassword.ts @@ -0,0 +1,41 @@ +import bcrypt from "bcryptjs"; +import jwtDecode from "jwt-decode"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { INVALID_OTP } from "../../../constants"; + +export const forgotPassword: MutationResolvers["forgotPassword"] = async ( + _parent, + args +) => { + const { userOtp, newPassword, otpToken } = args.data; + + // Extracts email and otp out of otpToken. + const { email, otp } = jwtDecode<{ + email: string; + otp: string; + }>(otpToken); + + // Compares otpToken and otp. + const otpIsValid = await bcrypt.compare(userOtp, otp); + + // Checks whether otp is valid. + if (otpIsValid === false) { + throw new Error(INVALID_OTP); + } + + const hashedPassword = await bcrypt.hash(newPassword, 12); + + // Updates password field for user's document with email === email. + await User.updateOne( + { + email, + }, + { + password: hashedPassword, + } + ); + + // Returns true if operation is successful. + return true; +}; diff --git a/src/lib/resolvers/Mutation/index.ts b/src/lib/resolvers/Mutation/index.ts new file mode 100644 index 0000000000..bed69188c5 --- /dev/null +++ b/src/lib/resolvers/Mutation/index.ts @@ -0,0 +1,138 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { acceptAdmin } from "./acceptAdmin"; +import { acceptMembershipRequest } from "./acceptMembershipRequest"; +import { addLanguageTranslation } from "./addLanguageTranslation"; +import { addOrganizationImage } from "./addOrganizationImage"; +import { addUserImage } from "./addUserImage"; +import { addUserToGroupChat } from "./addUserToGroupChat"; +import { adminRemoveEvent } from "./adminRemoveEvent"; +import { adminRemoveGroup } from "./adminRemoveGroup"; +import { adminRemovePost } from "./adminRemovePost"; +import { blockPluginCreationBySuperadmin } from "./blockPluginCreationBySuperadmin"; +import { blockUser } from "./blockUser"; +import { cancelMembershipRequest } from "./cancelMembershipRequest"; +import { createAdmin } from "./createAdmin"; +import { createComment } from "./createComment"; +import { createDirectChat } from "./createDirectChat"; +import { createDonation } from "./createDonation"; +import { createEvent } from "./createEvent"; +import { createGroupChat } from "./createGroupChat"; +import { createMessageChat } from "./createMessageChat"; +import { createOrganization } from "./createOrganization"; +import { createPlugin } from "./createPlugin"; +import { createPost } from "./createPost"; +import { createTask } from "./createTask"; +import { deleteDonationById } from "./deleteDonationById"; +import { forgotPassword } from "./forgotPassword"; +import { joinPublicOrganization } from "./joinPublicOrganization"; +import { leaveOrganization } from "./leaveOrganization"; +import { likeComment } from "./likeComment"; +import { likePost } from "./likePost"; +import { login } from "./login"; +import { logout } from "./logout"; +import { otp } from "./otp"; +import { recaptcha } from "./recaptcha"; +import { refreshToken } from "./refreshToken"; +import { registerForEvent } from "./registerForEvent"; +import { rejectAdmin } from "./rejectAdmin"; +import { rejectMembershipRequest } from "./rejectMembershipRequest"; +import { removeAdmin } from "./removeAdmin"; +import { removeComment } from "./removeComment"; +import { removeDirectChat } from "./removeDirectChat"; +import { removeEvent } from "./removeEvent"; +import { removeGroupChat } from "./removeGroupChat"; +import { removeMember } from "./removeMember"; +import { removeOrganization } from "./removeOrganization"; +import { removeOrganizationImage } from "./removeOrganizationImage"; +import { removePost } from "./removePost"; +import { removeTask } from "./removeTask"; +import { removeUserFromGroupChat } from "./removeUserFromGroupChat"; +import { removeUserImage } from "./removeUserImage"; +import { revokeRefreshTokenForUser } from "./revokeRefreshTokenForUser"; +import { saveFcmToken } from "./saveFcmToken"; +import { sendMembershipRequest } from "./sendMembershipRequest"; +import { sendMessageToDirectChat } from "./sendMessageToDirectChat"; +import { sendMessageToGroupChat } from "./sendMessageToGroupChat"; +import { signUp } from "./signUp"; +import { unblockUser } from "./unblockUser"; +import { unlikeComment } from "./unlikeComment"; +import { unlikePost } from "./unlikePost"; +import { unregisterForEventByUser } from "./unregisterForEventByUser"; +import { updateEvent } from "./updateEvent"; +import { updateLanguage } from "./updateLanguage"; +import { updateOrganization } from "./updateOrganization"; +import { updatePluginInstalledOrgs } from "./updatePluginInstalledOrgs"; +import { updatePluginStatus } from "./updatePluginStatus"; +import { updateTask } from "./updateTask"; +import { updateUserProfile } from "./updateUserProfile"; +import { updateUserType } from "./updateUserType"; + +export const Mutation: MutationResolvers = { + acceptAdmin, + acceptMembershipRequest, + addLanguageTranslation, + addOrganizationImage, + addUserImage, + addUserToGroupChat, + adminRemoveEvent, + adminRemoveGroup, + adminRemovePost, + blockPluginCreationBySuperadmin, + blockUser, + cancelMembershipRequest, + createAdmin, + createComment, + createDirectChat, + createDonation, + createEvent, + createGroupChat, + createMessageChat, + createOrganization, + createPlugin, + createPost, + createTask, + deleteDonationById, + forgotPassword, + joinPublicOrganization, + leaveOrganization, + likeComment, + likePost, + login, + logout, + otp, + recaptcha, + refreshToken, + registerForEvent, + rejectAdmin, + rejectMembershipRequest, + removeAdmin, + removeComment, + removeDirectChat, + removeEvent, + removeGroupChat, + removeMember, + removeOrganization, + removeOrganizationImage, + removePost, + removeTask, + removeUserFromGroupChat, + removeUserImage, + revokeRefreshTokenForUser, + saveFcmToken, + sendMembershipRequest, + sendMessageToDirectChat, + sendMessageToGroupChat, + signUp, + unblockUser, + unlikeComment, + unlikePost, + unregisterForEventByUser, + updateEvent, + updateLanguage, + updateOrganization, + updatePluginInstalledOrgs, + updatePluginStatus, + updateTask, + updateUserProfile, + updateUserType, +}; diff --git a/src/lib/resolvers/Mutation/joinPublicOrganization.ts b/src/lib/resolvers/Mutation/joinPublicOrganization.ts new file mode 100644 index 0000000000..0211dc59e1 --- /dev/null +++ b/src/lib/resolvers/Mutation/joinPublicOrganization.ts @@ -0,0 +1,113 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Organization } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_ALREADY_MEMBER, + USER_ALREADY_MEMBER_CODE, + USER_ALREADY_MEMBER_MESSAGE, + USER_ALREADY_MEMBER_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const joinPublicOrganization: MutationResolvers["joinPublicOrganization"] = + async (_parent, args, context) => { + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether organization is public. + if (organization.isPublic === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const currentUserIsOrganizationMember = organization.members.some( + (member) => member.toString() === context.userId.toString() + ); + + // Checks whether currentUser with _id === context.userId is already a member of organzation. + if (currentUserIsOrganizationMember === true) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? USER_ALREADY_MEMBER + : requestContext.translate(USER_ALREADY_MEMBER_MESSAGE), + USER_ALREADY_MEMBER_CODE, + USER_ALREADY_MEMBER_PARAM + ); + } + + // Adds context.userId to members list of organzation's document. + await Organization.updateOne( + { + _id: organization._id, + }, + { + $push: { + members: context.userId, + }, + } + ); + + /* + Adds organization._id to joinedOrganizations list of currentUser's document + with _id === context.userId and returns the updated currentUser. + */ + return await User.findOneAndUpdate( + { + _id: context.userId, + }, + { + $push: { + joinedOrganizations: organization._id, + }, + }, + { + new: true, + } + ) + .select(["-password"]) + .lean(); + }; diff --git a/src/lib/resolvers/Mutation/leaveOrganization.ts b/src/lib/resolvers/Mutation/leaveOrganization.ts new file mode 100644 index 0000000000..a3ef7f7bac --- /dev/null +++ b/src/lib/resolvers/Mutation/leaveOrganization.ts @@ -0,0 +1,124 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Organization } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + MEMBER_NOT_FOUND_MESSAGE, + MEMBER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED_PARAM, + MEMBER_NOT_FOUND_CODE, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_CODE, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + USER_NOT_FOUND, + USER_NOT_AUTHORIZED_MESSAGE, + MEMBER_NOT_FOUND, +} from "../../../constants"; + +export const leaveOrganization: MutationResolvers["leaveOrganization"] = async ( + _parent, + args, + context +) => { + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser is the creator of organzation. + if (currentUser._id.toString() === organization.creator.toString()) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + const currentUserIsOrganizationMember = organization.members.some( + (member) => member.toString() === currentUser!._id.toString() + ); + + // Checks whether currentUser is not a member of organzation. + if (currentUserIsOrganizationMember === false) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? MEMBER_NOT_FOUND + : requestContext.translate(MEMBER_NOT_FOUND_MESSAGE), + MEMBER_NOT_FOUND_CODE, + MEMBER_NOT_FOUND_PARAM + ); + } + + // Removes currentUser._id from admins and members lists of organzation's document. + await Organization.updateOne( + { + _id: organization._id, + }, + { + $set: { + admins: organization.admins.filter( + (admin) => admin.toString() !== currentUser!._id.toString() + ), + members: organization.members.filter( + (member) => member.toString() !== currentUser!._id.toString() + ), + }, + } + ); + + /* + Removes organization._id from joinedOrganizations list of currentUser's document + and returns the updated currentUser. + */ + return await User.findOneAndUpdate( + { + _id: currentUser._id, + }, + { + $set: { + joinedOrganizations: currentUser.joinedOrganizations.filter( + (joinedOrganization) => + joinedOrganization.toString() !== organization._id.toString() + ), + }, + }, + { + new: true, + } + ) + .select(["-password"]) + .lean(); +}; diff --git a/src/lib/resolvers/Mutation/likeComment.ts b/src/lib/resolvers/Mutation/likeComment.ts new file mode 100644 index 0000000000..9e7d282f7b --- /dev/null +++ b/src/lib/resolvers/Mutation/likeComment.ts @@ -0,0 +1,81 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Comment } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + COMMENT_NOT_FOUND, + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_MESSAGE, + COMMENT_NOT_FOUND_PARAM, + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const likeComment: MutationResolvers["likeComment"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id == context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const comment = await Comment.findOne({ + _id: args.id, + }).lean(); + + // Checks whether comment exists. + if (!comment) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? COMMENT_NOT_FOUND + : requestContext.translate(COMMENT_NOT_FOUND_MESSAGE), + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_PARAM + ); + } + + const currentUserHasLikedComment = comment.likedBy.some( + (likedByUser) => likedByUser.toString() === context.userId.toString() + ); + + // Checks whether currentUser with _id === context.userId has not already liked the comment. + if (currentUserHasLikedComment === false) { + /* + Adds context.userId to likedBy list and increases likeCount field by 1 + of comment's document and returns the updated comment. + */ + return await Comment.findOneAndUpdate( + { + _id: comment._id, + }, + { + $push: { + likedBy: context.userId, + }, + $inc: { + likeCount: 1, + }, + }, + { + new: true, + } + ).lean(); + } + + // Returns the comment without liking. + return comment; +}; diff --git a/src/lib/resolvers/Mutation/likePost.ts b/src/lib/resolvers/Mutation/likePost.ts new file mode 100644 index 0000000000..a3b852aacf --- /dev/null +++ b/src/lib/resolvers/Mutation/likePost.ts @@ -0,0 +1,81 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Post } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + POST_NOT_FOUND, + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_MESSAGE, + POST_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const likePost: MutationResolvers["likePost"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id == context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const post = await Post.findOne({ + _id: args.id, + }).lean(); + + // Checks whether post exists. + if (!post) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? POST_NOT_FOUND + : requestContext.translate(POST_NOT_FOUND_MESSAGE), + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_PARAM + ); + } + + const currentUserHasLikedPost = post.likedBy.some( + (likedByUser) => likedByUser.toString() === context.userId.toString() + ); + + // Checks whether currentUser with _id === context.userId has not already liked the post. + if (currentUserHasLikedPost === false) { + /* + Adds context.userId to likedBy list and increases likeCount field by 1 + of post's document and returns the updated post. + */ + return await Post.findOneAndUpdate( + { + _id: args.id, + }, + { + $push: { + likedBy: context.userId, + }, + $inc: { + likeCount: 1, + }, + }, + { + new: true, + } + ).lean(); + } + + // Returns the post without liking. + return post; +}; diff --git a/src/lib/resolvers/Mutation/login.ts b/src/lib/resolvers/Mutation/login.ts new file mode 100644 index 0000000000..eee123b158 --- /dev/null +++ b/src/lib/resolvers/Mutation/login.ts @@ -0,0 +1,89 @@ +import bcrypt from "bcryptjs"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { + createAccessToken, + createRefreshToken, + copyToClipboard, +} from "../../utilities"; +import { errors, requestContext } from "../../libraries"; +import { androidFirebaseOptions, iosFirebaseOptions } from "../../config"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const login: MutationResolvers["login"] = async (_parent, args) => { + let user = await User.findOne({ + email: args.data.email.toLowerCase(), + }).lean(); + + // Checks whether user exists. + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const isPasswordValid = await bcrypt.compare( + args.data.password, + user.password + ); + + // Checks whether password is invalid. + if (isPasswordValid === false) { + throw new errors.ValidationError( + [ + { + message: + IN_PRODUCTION !== true + ? "Invalid credentials" + : requestContext.translate("invalid.credentials"), + code: "invalid.credentials", + param: "credentials", + }, + ], + IN_PRODUCTION !== true + ? "Invalid credentials" + : requestContext.translate("invalid.credentials") + ); + } + + const accessToken = await createAccessToken(user); + const refreshToken = await createRefreshToken(user); + + copyToClipboard(`{ + "Authorization": "Bearer ${accessToken}" + }`); + + // Assigns new value with populated fields to user object. + user = await User.findOne({ + _id: user._id, + }) + .select(["-password"]) + .populate("joinedOrganizations") + .populate("createdOrganizations") + .populate("createdEvents") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .populate("membershipRequests") + .populate("organizationsBlockedBy") + .populate("organizationUserBelongsTo") + .lean(); + + return { + user: user!, + accessToken, + refreshToken, + androidFirebaseOptions, + iosFirebaseOptions, + }; +}; diff --git a/src/lib/resolvers/Mutation/logout.ts b/src/lib/resolvers/Mutation/logout.ts new file mode 100644 index 0000000000..9c17ccac5b --- /dev/null +++ b/src/lib/resolvers/Mutation/logout.ts @@ -0,0 +1,46 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + USER_NOT_FOUND, + IN_PRODUCTION, +} from "../../../constants"; + +export const logout: MutationResolvers["logout"] = async ( + _parent, + _args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id == context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Sets token field of currentUser with _id === context.userId to null. + await User.updateOne( + { + _id: context.userId, + }, + { + $set: { + token: null, + }, + } + ); + + // Returns true if the operation is successful. + return true; +}; diff --git a/src/lib/resolvers/Mutation/otp.ts b/src/lib/resolvers/Mutation/otp.ts new file mode 100644 index 0000000000..fa2cba5535 --- /dev/null +++ b/src/lib/resolvers/Mutation/otp.ts @@ -0,0 +1,45 @@ +import bcrypt from "bcryptjs"; +import jwt from "jsonwebtoken"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { mailer } from "../../utilities"; +import { USER_NOT_FOUND } from "../../../constants"; + +export const otp: MutationResolvers["otp"] = async (_parent, args) => { + const user = await User.findOne({ + email: args.data.email, + }).lean(); + + if (!user) { + throw new Error(USER_NOT_FOUND); + } + + const username = `${user.firstName} ${user.lastName}`; + + const otp = (Math.floor(Math.random() * 10000) + 9999).toString(); + + const hashedOtp = await bcrypt.hash(otp, 10); + + const otpToken = jwt.sign( + { + email: args.data.email, + otp: hashedOtp, + }, + process.env.ACCESS_TOKEN_SECRET!, + { + expiresIn: "15m", + } + ); + + const subject = "OTP for Talawa-admin forgot password"; + const body = `

Hi, ${username}

Your OTP: ${otp}

Your OTP will expires in 5 minutes.



Do not share your otp with others.`; + + return mailer({ + emailTo: args.data.email, + subject, + body, + }).then((info) => { + console.log(info); + return { otpToken }; + }); +}; diff --git a/src/lib/resolvers/Mutation/recaptcha.ts b/src/lib/resolvers/Mutation/recaptcha.ts new file mode 100644 index 0000000000..85ccdec3d7 --- /dev/null +++ b/src/lib/resolvers/Mutation/recaptcha.ts @@ -0,0 +1,13 @@ +import axios from "axios"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; + +export const recaptcha: MutationResolvers["recaptcha"] = async ( + _parent, + args +) => { + const response = await axios.post( + `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${args.data.recaptchaToken}` + ); + + return response.data.success; +}; diff --git a/src/lib/resolvers/Mutation/refreshToken.ts b/src/lib/resolvers/Mutation/refreshToken.ts new file mode 100644 index 0000000000..ec66cdee52 --- /dev/null +++ b/src/lib/resolvers/Mutation/refreshToken.ts @@ -0,0 +1,85 @@ +import jwt from "jsonwebtoken"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User } from "../../models"; +import { createAccessToken, createRefreshToken } from "../../utilities"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { Interface_JwtTokenPayload } from "../../utilities"; + +export const refreshToken: MutationResolvers["refreshToken"] = async ( + _parent, + args +) => { + // This route should not be protected because the access token will be expired. + if (!args.refreshToken) { + throw new errors.ValidationError( + [ + { + message: + IN_PRODUCTION !== true + ? "Invalid refreshToken" + : requestContext.translate("invalid.refreshToken"), + code: "invalid.refreshToken", + param: "refreshToken", + }, + ], + IN_PRODUCTION !== true + ? "Invalid refreshToken" + : requestContext.translate("invalid.refreshToken") + ); + } + + const jwtPayload: Interface_JwtTokenPayload = jwt.verify( + args.refreshToken, + process.env.REFRESH_TOKEN_SECRET! + ) as Interface_JwtTokenPayload; + + // The refresh token received is valid so we can send a new access token + const user = await User.findOne({ + _id: jwtPayload.userId, + }).lean(); + + // Checks whether user exists. + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + if (user.tokenVersion !== jwtPayload.tokenVersion) { + throw new errors.ValidationError( + [ + { + message: + IN_PRODUCTION !== true + ? "Invalid refreshToken" + : requestContext.translate("invalid.refreshToken"), + code: "invalid.refreshToken", + param: "refreshToken", + }, + ], + IN_PRODUCTION !== true + ? "Invalid refreshToken" + : requestContext.translate("invalid.refreshToken") + ); + } + + // send new access and refresh token to user + const newAccessToken = await createAccessToken(user); + const newRefreshToken = await createRefreshToken(user); + + return { + accessToken: newAccessToken, + refreshToken: newRefreshToken, + }; +}; diff --git a/src/lib/resolvers/Mutation/registerForEvent.ts b/src/lib/resolvers/Mutation/registerForEvent.ts new file mode 100644 index 0000000000..fbb33d8455 --- /dev/null +++ b/src/lib/resolvers/Mutation/registerForEvent.ts @@ -0,0 +1,139 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Event } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM, + REGISTRANT_ALREADY_EXIST, + REGISTRANT_ALREADY_EXIST_CODE, + REGISTRANT_ALREADY_EXIST_MESSAGE, + REGISTRANT_ALREADY_EXIST_PARAM, +} from "../../../constants"; + +export const registerForEvent: MutationResolvers["registerForEvent"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id == context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const event = await Event.findOne({ + _id: args.id, + }).lean(); + + // Checks whether event exists. + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + const index = event.registrants.findIndex((registrant) => { + return registrant.userId.toString() === context.userId.toString(); + }); + + let currentUserIsEventRegistrant = false; + + // Checks whether currentUser with _id === context.userId is already a registrant for event. + if (index !== -1) { + if (event.registrants[index].status === "ACTIVE") { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? REGISTRANT_ALREADY_EXIST + : requestContext.translate(REGISTRANT_ALREADY_EXIST_MESSAGE), + REGISTRANT_ALREADY_EXIST_CODE, + REGISTRANT_ALREADY_EXIST_PARAM + ); + } else { + currentUserIsEventRegistrant = true; + } + } + + // Checks whether currentUser with _id === context.userId is not registrant of event. + if (currentUserIsEventRegistrant === false) { + // Adds event._id to registeredEvents list of currentUser with _id === context.userId. + await User.updateOne( + { + _id: context.userId, + }, + { + $push: { + registeredEvents: event._id, + }, + } + ); + + /* + Adds currentUser with _id === context.userId new registrant to registrants + list of event and returns the updated event. + */ + return await Event.findOneAndUpdate( + { + _id: event._id, + status: "ACTIVE", + }, + { + $push: { + registrants: { + userId: context.userId, + user: context.userId, + }, + }, + }, + { + new: true, + } + ).lean(); + } else { + const updatedRegistrants = event.registrants; + + // Sets registrant.status for user with _id === context.userId of event to ACTIVE. + updatedRegistrants[index] = { + id: updatedRegistrants[index].id, + userId: updatedRegistrants[index].userId, + user: updatedRegistrants[index].user, + status: "ACTIVE", + createdAt: updatedRegistrants[index].createdAt, + }; + + // Sets updatedRegistrants as registrants list of event and returns the updated event. + return await Event.findOneAndUpdate( + { + _id: event._id, + status: "ACTIVE", + }, + { + $set: { + registrants: updatedRegistrants, + }, + }, + { + new: true, + } + ).lean(); + } +}; diff --git a/src/lib/resolvers/Mutation/rejectAdmin.ts b/src/lib/resolvers/Mutation/rejectAdmin.ts new file mode 100644 index 0000000000..b93a9200ec --- /dev/null +++ b/src/lib/resolvers/Mutation/rejectAdmin.ts @@ -0,0 +1,60 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { errors, requestContext } from "../../libraries"; + +export const rejectAdmin: MutationResolvers["rejectAdmin"] = async ( + _parent, + args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser is not a SUPERADMIN. + if (currentUser.userType !== "SUPERADMIN") { + throw new Error(USER_NOT_AUTHORIZED); + } + + const userExists = await User.exists({ + _id: args.id, + }); + + // Checks whether user with _id === args.id exists. + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Deletes the user. + await User.deleteOne({ + _id: args.id, + }); + + // Returns true if operation is successful. + return true; +}; diff --git a/src/lib/resolvers/Mutation/rejectMembershipRequest.ts b/src/lib/resolvers/Mutation/rejectMembershipRequest.ts new file mode 100644 index 0000000000..f3dc3a1851 --- /dev/null +++ b/src/lib/resolvers/Mutation/rejectMembershipRequest.ts @@ -0,0 +1,106 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Organization, MembershipRequest } from "../../models"; +import { adminCheck } from "../../utilities"; +import { + MEMBERSHIP_REQUEST_NOT_FOUND, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + USER_NOT_FOUND, + MEMBERSHIP_REQUEST_NOT_FOUND_CODE, + MEMBERSHIP_REQUEST_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND_MESSAGE, + MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_MESSAGE, +} from "../../../constants"; + +export const rejectMembershipRequest: MutationResolvers["rejectMembershipRequest"] = + async (_parent, args, context) => { + const membershipRequest = await MembershipRequest.findOne({ + _id: args.membershipRequestId, + }).lean(); + + // Checks whether membershipRequest exists. + if (!membershipRequest) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? MEMBERSHIP_REQUEST_NOT_FOUND + : requestContext.translate(MEMBERSHIP_REQUEST_NOT_FOUND_MESSAGE), + MEMBERSHIP_REQUEST_NOT_FOUND_CODE, + MEMBERSHIP_REQUEST_NOT_FOUND_PARAM + ); + } + + const organzation = await Organization.findOne({ + _id: membershipRequest.organization, + }).lean(); + + // Checks whether organization exists. + if (!organzation) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const user = await User.findOne({ + _id: membershipRequest.user, + }).lean(); + + // Checks whether user exists. + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization. + adminCheck(context.userId, organzation); + + // Deletes the membershipRequest. + await MembershipRequest.deleteOne({ + _id: membershipRequest._id, + }); + + // Removes membershipRequest._id from membershipRequests list of organization. + await Organization.updateOne( + { + _id: organzation._id, + }, + { + $set: { + membershipRequests: organzation.membershipRequests.filter( + (request) => request.toString() !== membershipRequest._id.toString() + ), + }, + } + ); + + // Removes membershipRequest._id from membershipRequests list of user. + await User.updateOne( + { + _id: user._id, + }, + { + $set: { + membershipRequests: user.membershipRequests.filter( + (request) => request.toString() !== membershipRequest._id.toString() + ), + }, + } + ); + + // Returns deleted membershipRequest. + return membershipRequest; + }; diff --git a/src/lib/resolvers/Mutation/removeAdmin.ts b/src/lib/resolvers/Mutation/removeAdmin.ts new file mode 100644 index 0000000000..99dc39a109 --- /dev/null +++ b/src/lib/resolvers/Mutation/removeAdmin.ts @@ -0,0 +1,91 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { adminCheck, creatorCheck } from "../../utilities"; +import { User, Organization } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_PARAM, + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + USER_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, +} from "../../../constants"; + +export const removeAdmin: MutationResolvers["removeAdmin"] = async ( + _parent, + args, + context +) => { + const organization = await Organization.findOne({ + _id: args.data.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const user = await User.findOne({ + _id: args.data.userId, + }).lean(); + + // Checks whether user exists. + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether user is an admin of organization. + adminCheck(user._id, organization); + + // Checks whether currentUser with _id === context.userId is the creator of organization. + creatorCheck(context.userId, organization); + + // Removes user._id from admins list of the organization. + await Organization.updateOne( + { + _id: organization._id, + }, + { + $set: { + admins: organization.admins.filter( + (admin) => admin.toString() !== user!._id.toString() + ), + }, + } + ); + + // Removes organization._id from adminFor list of the user and returns the updated user. + return await User.findOneAndUpdate( + { + _id: user._id, + }, + { + $set: { + adminFor: user.adminFor.filter( + (adminForOrganization) => + adminForOrganization.toString() !== organization._id.toString() + ), + }, + }, + { + new: true, + } + ) + .select(["-password"]) + .lean(); +}; diff --git a/src/lib/resolvers/Mutation/removeComment.ts b/src/lib/resolvers/Mutation/removeComment.ts new file mode 100644 index 0000000000..4150de40d6 --- /dev/null +++ b/src/lib/resolvers/Mutation/removeComment.ts @@ -0,0 +1,90 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User, Post, Comment } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + IN_PRODUCTION, + COMMENT_NOT_FOUND, + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_MESSAGE, + COMMENT_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, +} from "../../../constants"; + +export const removeComment: MutationResolvers["removeComment"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const comment = await Comment.findOne({ + _id: args.id, + }).lean(); + + // Checks whether comment exists. + if (!comment) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? COMMENT_NOT_FOUND + : requestContext.translate(COMMENT_NOT_FOUND_MESSAGE), + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is not the creator of comment. + if (comment.creator.toString() !== context.userId.toString()) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_FOUND_PARAM + ); + } + + /* + Removes comment._id from comments list and reduces commentCount + by 1 of post with _id === comment.post + */ + await Post.updateOne( + { + _id: comment.post, + }, + { + $pull: { + comments: comment._id, + }, + $inc: { + commentCount: -1, + }, + } + ); + + // Deletes the comment. + await Comment.deleteOne({ + _id: comment._id, + }); + + // Returns the deleted comment. + return comment; +}; diff --git a/src/lib/resolvers/Mutation/removeDirectChat.ts b/src/lib/resolvers/Mutation/removeDirectChat.ts new file mode 100644 index 0000000000..c822c5b42a --- /dev/null +++ b/src/lib/resolvers/Mutation/removeDirectChat.ts @@ -0,0 +1,69 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { DirectChat, DirectChatMessage, Organization } from "../../models"; +import { adminCheck } from "../../utilities"; +import { errors, requestContext } from "../../libraries"; +import { + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_MESSAGE, + CHAT_NOT_FOUND_PARAM, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const removeDirectChat: MutationResolvers["removeDirectChat"] = async ( + _parent, + args, + context +) => { + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const directChat = await DirectChat.findOne({ + _id: args.chatId, + }).lean(); + + // Checks whether directChat exists. + if (!directChat) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organzation. + adminCheck(context.userId, organization); + + // Deletes all directChatMessages with _id as one of the ids in directChat.messages list. + await DirectChatMessage.deleteMany({ + _id: { + $in: directChat.messages, + }, + }); + + // Deletes the directChat. + await DirectChat.deleteOne({ + _id: args.chatId, + }); + + // Returns deleted directChat. + return directChat; +}; diff --git a/src/lib/resolvers/Mutation/removeEvent.ts b/src/lib/resolvers/Mutation/removeEvent.ts new file mode 100644 index 0000000000..9ff299e08e --- /dev/null +++ b/src/lib/resolvers/Mutation/removeEvent.ts @@ -0,0 +1,108 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Event } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; + +export const removeEvent: MutationResolvers["removeEvent"] = async ( + _parent, + args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const event = await Event.findOne({ + _id: args.id, + }).lean(); + + // Checks whether event exists. + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + // Boolean to determine whether user is an admin of organization. + const currentUserIsOrganizationAdmin = currentUser.adminFor.some( + (organization) => organization.toString() === event.organization.toString() + ); + + // Boolean to determine whether user is an admin of event. + const currentUserIsEventAdmin = event.admins.some( + (admin) => admin.toString() === currentUser._id.toString() + ); + + // Checks whether currentUser cannot delete event. + if (!(currentUserIsOrganizationAdmin || currentUserIsEventAdmin)) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + await User.updateMany( + { + createdEvents: event._id, + }, + { + $pull: { + createdEvents: event._id, + }, + } + ); + + await User.updateMany( + { + eventAdmin: event._id, + }, + { + $pull: { + eventAdmin: event._id, + }, + } + ); + + await Event.updateOne( + { + _id: event._id, + }, + { + status: "DELETED", + } + ); + + return event; +}; diff --git a/src/lib/resolvers/Mutation/removeEventProject.ts b/src/lib/resolvers/Mutation/removeEventProject.ts new file mode 100644 index 0000000000..b27aff242f --- /dev/null +++ b/src/lib/resolvers/Mutation/removeEventProject.ts @@ -0,0 +1,70 @@ +import { User, EventProject } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + EVENT_PROJECT_NOT_FOUND, + EVENT_PROJECT_NOT_FOUND_CODE, + EVENT_PROJECT_NOT_FOUND_MESSAGE, + EVENT_PROJECT_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; + +export const removeEventProject = async ( + _parent: any, + args: any, + context: any +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks if currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const eventProject = await EventProject.findOne({ + _id: args.id, + }).lean(); + + // Checks whether eventProject exists. + if (!eventProject) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_PROJECT_NOT_FOUND + : requestContext.translate(EVENT_PROJECT_NOT_FOUND_MESSAGE), + EVENT_PROJECT_NOT_FOUND_CODE, + EVENT_PROJECT_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is not the creator of eventProject. + if (eventProject.creator.toString() !== context.userId.toString()) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + await EventProject.deleteOne({ + _id: args.id, + }); + + return eventProject; +}; diff --git a/src/lib/resolvers/Mutation/removeGroupChat.ts b/src/lib/resolvers/Mutation/removeGroupChat.ts new file mode 100644 index 0000000000..28739752e7 --- /dev/null +++ b/src/lib/resolvers/Mutation/removeGroupChat.ts @@ -0,0 +1,68 @@ +import { adminCheck } from "../../utilities"; +import { + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_MESSAGE, + CHAT_NOT_FOUND_PARAM, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { GroupChat, GroupChatMessage, Organization } from "../../models"; + +export const removeGroupChat: MutationResolvers["removeGroupChat"] = async ( + _parent, + args, + context +) => { + const groupChat = await GroupChat.findOne({ + _id: args.chatId, + }).lean(); + + // Checks if a groupChat with _id === args.chatId exists. + if (!groupChat) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: groupChat.organization, + }).lean(); + + // Checks if an organization with _id === groupChat.organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether current user making the request is an admin of organization. + adminCheck(context.userId, organization); + + // Delete all groupChatMessages that have their ids stored in messages list of groupChat + await GroupChatMessage.deleteMany({ + _id: { + $in: groupChat.messages, + }, + }); + + // Delete the groupChat + await GroupChat.deleteOne({ + _id: groupChat._id, + }); + + return groupChat; +}; diff --git a/src/lib/resolvers/Mutation/removeMember.ts b/src/lib/resolvers/Mutation/removeMember.ts new file mode 100644 index 0000000000..be7a36ca34 --- /dev/null +++ b/src/lib/resolvers/Mutation/removeMember.ts @@ -0,0 +1,140 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Organization } from "../../models"; +import { adminCheck } from "../../utilities"; +import { + USER_NOT_FOUND, + MEMBER_NOT_FOUND, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const removeMember: MutationResolvers["removeMember"] = async ( + _parent, + args, + context +) => { + let organization = await Organization.findOne({ + _id: args.data.organizationId, + }).lean(); + + // Checks if organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether current user making the request is an admin of organization. + adminCheck(context.userId, organization); + + /* + Errors inside a loop stop the loop it doesnt throw the error, errors have to be + stored in an array an thrown at the end. This variable is used to store all the + errors we want to throw from the following for loop. + */ + const errorsToThrow = []; + + for await (const userId of args.data.userIds) { + // do not run an async function inside a for each loop - it doesnt work + + const user = await User.findOne({ + _id: userId, + }).lean(); + + // Checks if a user with _id === userId exists. + if (!user) { + errorsToThrow.push(USER_NOT_FOUND); + break; + } + + // Boolean to determine whether user is a member of organization. + const userIsOrganizationMember = organization?.members.some( + (member) => member.toString() === user._id.toString() + ); + + /* + userIsOrganizationMember being true implies that the current user is a member of organization. + If userIsOrganizationMember is false pushes error message to errors list and breaks out of loop. + */ + if (userIsOrganizationMember === false) { + errorsToThrow.push(MEMBER_NOT_FOUND); + break; + } + + // Boolean to determine whether user is an admin of organization. + const userIsOrganizationAdmin = organization?.admins.some( + (admin) => admin.toString() === user._id.toString() + ); + + /* + userIsOrganizationAdmin being true implies that the current user is an admin of organization. + If userIsOrganizationAdmin is true pushes error message to errors list and breaks out of loop. + */ + if (userIsOrganizationAdmin === true) { + errorsToThrow.push( + "Administrators cannot remove members who are also Administrators" + ); + break; + } + + /* + Administrators cannot remove creator of organzation from the members list. + Following if block matches organization's creator's id to + user's id. Match being true implies that current user is the creator + of organization. If match is true assigns error message to errors list + and breaks out of loop. + */ + if (organization?.creator.toString() === user._id.toString()) { + errorsToThrow.push( + "Administrators cannot remove the creator of the organization from the organization" + ); + break; + } + + // Removes user's id from members list on organization. + organization = await Organization.findOneAndUpdate( + { + _id: organization?._id, + }, + { + $set: { + members: organization?.members.filter( + (member) => member.toString() !== user._id.toString() + ), + }, + }, + { + new: true, + } + ).lean(); + + // Remove organization's id from joinedOrganizations list on user. + await User.updateOne( + { + _id: user._id, + }, + { + $set: { + joinedOrganizations: user.joinedOrganizations.filter( + (joinedOrganization) => + joinedOrganization.toString() !== organization?._id.toString() + ), + }, + } + ); + } + + if (errorsToThrow.length > 0) { + throw new Error(errorsToThrow.join()); + } + + return organization!; +}; diff --git a/src/lib/resolvers/Mutation/removeOrganization.ts b/src/lib/resolvers/Mutation/removeOrganization.ts new file mode 100644 index 0000000000..417ebb4622 --- /dev/null +++ b/src/lib/resolvers/Mutation/removeOrganization.ts @@ -0,0 +1,189 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { + User, + Organization, + Post, + Comment, + MembershipRequest, +} from "../../models"; +import { creatorCheck } from "../../utilities"; +import { + USER_NOT_FOUND, + IN_PRODUCTION, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const removeOrganization: MutationResolvers["removeOrganization"] = + async (_parent, args, context) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: args.id, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser is the creator of organization. + creatorCheck(currentUser._id, organization); + + // Remove each post and comments associated to it for organization.posts list. + organization.posts.forEach(async (postId) => { + await Post.deleteOne({ + _id: postId, + }); + + await Comment.deleteMany({ + post: postId, + }); + }); + + // Remove organization._id from createdOrganizations list of currentUser. + await User.updateOne( + { + _id: currentUser._id, + }, + { + $set: { + createdOrganizations: currentUser.createdOrganizations.filter( + (createdOrganization) => + createdOrganization.toString() !== organization._id.toString() + ), + }, + } + ); + + // Remove organization._id from each member's joinedOrganizations field for organization.members list. + for (const memberId of organization.members) { + const member = await User.findOne({ + _id: memberId, + }).lean(); + + await User.updateOne( + { + _id: memberId, + }, + { + $set: { + joinedOrganizations: member?.joinedOrganizations.filter( + (joinedOrganization) => + joinedOrganization.toString() !== organization._id.toString() + ), + }, + } + ); + } + + // Remove organization._id from each admin's joinedOrganizations field for organization.admins list. + for (const adminId of organization.admins) { + const admin = await User.findOne({ + _id: adminId, + }).lean(); + + await User.updateOne( + { + _id: adminId, + }, + { + $set: { + joinedOrganizations: admin?.joinedOrganizations.filter( + (joinedOrganization) => + joinedOrganization.toString() !== organization._id.toString() + ), + }, + } + ); + } + + /* + Remove membershipRequest._id from each requester's membershipRequests + field for membershipRequest.user for organization.membershipRequests list. + */ + for (const membershipRequestId of organization.membershipRequests) { + const membershipRequest = await MembershipRequest.findOneAndDelete({ + _id: membershipRequestId, + }).lean(); + + const requester = await User.findOne({ + _id: membershipRequest?.user, + }).lean(); + + await User.updateOne( + { + _id: requester?._id, + }, + { + $set: { + membershipRequests: requester?.membershipRequests.filter( + (request) => + request.toString() !== membershipRequest?._id.toString() + ), + }, + } + ); + } + + /* + Remove organization._id from each blockedUser's organizationsBlockedBy + field for organization.blockedUsers list. + */ + for (const blockedUserId of organization.blockedUsers) { + const blockedUser = await User.findOne({ + _id: blockedUserId, + }).lean(); + + await User.updateOne( + { + _id: blockedUser?._id, + }, + { + $set: { + organizationsBlockedBy: blockedUser?.organizationsBlockedBy.filter( + (organizationBlockedBy) => + organizationBlockedBy.toString() !== organization._id.toString() + ), + }, + } + ); + } + + // Deletes the organzation. + await Organization.deleteOne({ + _id: organization._id, + }); + + // Returns updated currentUser. + return await User.findOne({ + _id: currentUser._id, + }) + .select(["-password"]) + .lean(); + }; diff --git a/src/lib/resolvers/Mutation/removeOrganizationImage.ts b/src/lib/resolvers/Mutation/removeOrganizationImage.ts new file mode 100644 index 0000000000..c1d90e702e --- /dev/null +++ b/src/lib/resolvers/Mutation/removeOrganizationImage.ts @@ -0,0 +1,79 @@ +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Organization } from "../../models"; +import { adminCheck, deleteImage } from "../../utilities"; + +export const removeOrganizationImage: MutationResolvers["removeOrganizationImage"] = + async (_parent, args, context) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is an admin of organization + adminCheck(context.userId, organization); + + // Checks whether organization.image exists. + if (!organization.image) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? "Organization image not found" + : requestContext.translate("organization.profile.notFound"), + "organization.notFound", + "organization" + ); + } + + await deleteImage(organization.image); + + // Sets image field of organization to null and returns the updated organization. + return await Organization.findOneAndUpdate( + { + _id: organization._id, + }, + { + $set: { + image: null, + }, + }, + { + new: true, + } + ).lean(); + }; diff --git a/src/lib/resolvers/Mutation/removePost.ts b/src/lib/resolvers/Mutation/removePost.ts new file mode 100644 index 0000000000..6d36424397 --- /dev/null +++ b/src/lib/resolvers/Mutation/removePost.ts @@ -0,0 +1,73 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Post } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + POST_NOT_FOUND, + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_MESSAGE, + POST_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; + +export const removePost: MutationResolvers["removePost"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const post = await Post.findOne({ + _id: args.id, + }).lean(); + + // Checks whether post exists. + if (!post) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? POST_NOT_FOUND + : requestContext.translate(POST_NOT_FOUND_MESSAGE), + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id === context.userId is not the creator of post. + if (post.creator.toString() !== context.userId.toString()) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // Deletes the post. + await Post.deleteOne({ + _id: args.id, + }); + + // Returns deleted post. + return post; +}; diff --git a/src/lib/resolvers/Mutation/removeTask.ts b/src/lib/resolvers/Mutation/removeTask.ts new file mode 100644 index 0000000000..193b93932b --- /dev/null +++ b/src/lib/resolvers/Mutation/removeTask.ts @@ -0,0 +1,81 @@ +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Task, Event } from "../../models"; + +export const removeTask: MutationResolvers["removeTask"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // Checks whether currentUser with _id === context.userId exists. + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const task = await Task.findOne({ + _id: args.id, + }).lean(); + + // Checks whether task exists. + if (!task) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? "Task not found" + : requestContext.translate("task.notFound"), + "task.notFound", + "task" + ); + } + + // Checks whether currentUser with _id === context.userId is not the creator of task. + if (task.creator.toString() !== context.userId.toString()) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // Deletes the task. + await Task.deleteOne({ + _id: task._id, + }); + + // Removes task._id from tasks list of task.event. + await Event.updateMany( + { + _id: task.event, + }, + { + $pull: { + tasks: task._id, + }, + } + ); + + // Returns deleted task. + return task; +}; diff --git a/src/lib/resolvers/Mutation/removeUserFromGroupChat.ts b/src/lib/resolvers/Mutation/removeUserFromGroupChat.ts new file mode 100644 index 0000000000..5e9ce4c7e5 --- /dev/null +++ b/src/lib/resolvers/Mutation/removeUserFromGroupChat.ts @@ -0,0 +1,87 @@ +import { + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_MESSAGE, + CHAT_NOT_FOUND_PARAM, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_PARAM, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { GroupChat, Organization } from "../../models"; +import { adminCheck } from "../../utilities"; + +export const removeUserFromGroupChat: MutationResolvers["removeUserFromGroupChat"] = + async (_parent, args, context) => { + const groupChat = await GroupChat.findOne({ + _id: args.chatId, + }).lean(); + + // Checks whether groupChat exists. + if (!groupChat) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: groupChat.organization, + }).lean(); + + // Checks whether organization exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser with _id == context.userId is an admin of organzation. + adminCheck(context.userId, organization); + + const userIsMemberOfGroupChat = groupChat.users.some( + (user) => user.toString() === args.userId.toString() + ); + + // Checks if user with _id === args.userId is not a member of groupChat. + if (userIsMemberOfGroupChat === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // Removes args.userId from users list of groupChat and returns the updated groupChat. + return await GroupChat.findOneAndUpdate( + { + _id: args.chatId, + }, + { + $set: { + users: groupChat.users.filter( + (user) => user.toString() !== args.userId.toString() + ), + }, + }, + { + new: true, + } + ).lean(); + }; diff --git a/src/lib/resolvers/Mutation/removeUserImage.ts b/src/lib/resolvers/Mutation/removeUserImage.ts new file mode 100644 index 0000000000..690bbec9f8 --- /dev/null +++ b/src/lib/resolvers/Mutation/removeUserImage.ts @@ -0,0 +1,60 @@ +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User } from "../../models"; +import { deleteImage } from "../../utilities"; + +export const removeUserImage: MutationResolvers["removeUserImage"] = async ( + _parent, + _args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }); + + // Checks whether currentUser exists. + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Checks whether currentUser.image already doesn't exist. + if (!currentUser.image) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? "User profile image not found" + : requestContext.translate("user.profileImage.notFound"), + "user.profileImage.notFound", + "userProfileImage" + ); + } + + await deleteImage(currentUser.image); + + // Sets image field to null for currentUser and returns the updated currentUser. + return await User.findOneAndUpdate( + { + _id: currentUser._id, + }, + { + $set: { + image: null, + }, + }, + { + new: true, + } + ).lean(); +}; diff --git a/src/lib/resolvers/Mutation/revokeRefreshTokenForUser.ts b/src/lib/resolvers/Mutation/revokeRefreshTokenForUser.ts new file mode 100644 index 0000000000..bf343eb7f3 --- /dev/null +++ b/src/lib/resolvers/Mutation/revokeRefreshTokenForUser.ts @@ -0,0 +1,18 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const revokeRefreshTokenForUser: MutationResolvers["revokeRefreshTokenForUser"] = + async (_parent, args) => { + await User.updateOne( + { + _id: args.userId, + }, + { + $inc: { + tokenVersion: 1, + }, + } + ); + + return true; + }; diff --git a/src/lib/resolvers/Mutation/saveFcmToken.ts b/src/lib/resolvers/Mutation/saveFcmToken.ts new file mode 100644 index 0000000000..c48864dcf7 --- /dev/null +++ b/src/lib/resolvers/Mutation/saveFcmToken.ts @@ -0,0 +1,43 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const saveFcmToken: MutationResolvers["saveFcmToken"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + await User.updateOne( + { + _id: context.userId, + }, + { + $set: { + token: args.token, + }, + } + ); + + return true; +}; diff --git a/src/lib/resolvers/Mutation/sendMembershipRequest.ts b/src/lib/resolvers/Mutation/sendMembershipRequest.ts new file mode 100644 index 0000000000..58d3d9a986 --- /dev/null +++ b/src/lib/resolvers/Mutation/sendMembershipRequest.ts @@ -0,0 +1,91 @@ +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, MembershipRequest, Organization } from "../../models"; + +export const sendMembershipRequest: MutationResolvers["sendMembershipRequest"] = + async (_parent, args, context) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + const membershipRequestExists = await MembershipRequest.exists({ + user: context.userId, + organization: organization._id, + }); + + if (membershipRequestExists === true) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? "MembershipRequest already exists" + : requestContext.translate("membershipRequest.alreadyExists"), + "membershipRequest.alreadyExists", + "membershipRequest" + ); + } + + const createdMembershipRequest = await MembershipRequest.create({ + user: context.userId, + organization: organization._id, + }); + + // add membership request to organization + await Organization.updateOne( + { + _id: organization._id, + }, + { + $push: { + membershipRequests: createdMembershipRequest._id, + }, + } + ); + + // add membership request to user + await User.updateOne( + { + _id: context.userId, + }, + { + $push: { + membershipRequests: createdMembershipRequest._id, + }, + } + ); + + return createdMembershipRequest.toObject(); + }; diff --git a/src/lib/resolvers/Mutation/sendMessageToDirectChat.ts b/src/lib/resolvers/Mutation/sendMessageToDirectChat.ts new file mode 100644 index 0000000000..d25106f0fe --- /dev/null +++ b/src/lib/resolvers/Mutation/sendMessageToDirectChat.ts @@ -0,0 +1,77 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { DirectChat, DirectChatMessage, User } from "../../models"; +import { + IN_PRODUCTION, + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_MESSAGE, + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const sendMessageToDirectChat: MutationResolvers["sendMessageToDirectChat"] = + async (_parent, args, context) => { + const directChat = await DirectChat.findOne({ + _id: args.chatId, + }).lean(); + + if (!directChat) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // directChat.users can only have 2 users. So, the following method works. + const receiverIndex = directChat.users.findIndex( + (user) => user.toString() !== context.userId.toString() + ); + + const createdDirectChatMessage = await DirectChatMessage.create({ + directChatMessageBelongsTo: directChat._id, + sender: context.userId, + receiver: directChat.users[receiverIndex], + createdAt: new Date(), + messageContent: args.messageContent, + }); + + // add createdDirectChatMessage to directChat + await DirectChat.updateOne( + { + _id: directChat._id, + }, + { + $push: { + messages: createdDirectChatMessage._id, + }, + } + ); + + // calls subscription + context.pubsub.publish("MESSAGE_SENT_TO_DIRECT_CHAT", { + messageSentToDirectChat: createdDirectChatMessage.toObject(), + }); + + return createdDirectChatMessage.toObject(); + }; diff --git a/src/lib/resolvers/Mutation/sendMessageToGroupChat.ts b/src/lib/resolvers/Mutation/sendMessageToGroupChat.ts new file mode 100644 index 0000000000..4c8b4c6558 --- /dev/null +++ b/src/lib/resolvers/Mutation/sendMessageToGroupChat.ts @@ -0,0 +1,93 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { GroupChat, GroupChatMessage, User } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_PARAM, + CHAT_NOT_FOUND_MESSAGE, + CHAT_NOT_FOUND_CODE, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const sendMessageToGroupChat: MutationResolvers["sendMessageToGroupChat"] = + async (_parent, args, context) => { + const groupChat = await GroupChat.findOne({ + _id: args.chatId, + }).lean(); + + if (!groupChat) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const currentUserIsAMemberOfGroupChat = groupChat.users.some( + (user) => user.toString() === context.userId.toString() + ); + + /* + checks if users list of groupChat with _id === args.chatId contains + current user with _id === context.userId + */ + if (currentUserIsAMemberOfGroupChat === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + const createdGroupChatMessage = await GroupChatMessage.create({ + groupChatMessageBelongsTo: groupChat._id, + sender: context.userId, + createdAt: new Date(), + messageContent: args.messageContent, + }); + + // add createdGroupChatMessage to groupChat + await GroupChat.updateOne( + { + _id: args.chatId, + }, + { + $push: { + messages: createdGroupChatMessage._id, + }, + } + ); + + // calls subscription + context.pubsub.publish("MESSAGE_SENT_TO_GROUP_CHAT", { + messageSentToGroupChat: createdGroupChatMessage.toObject(), + }); + + return createdGroupChatMessage.toObject(); + }; diff --git a/src/lib/resolvers/Mutation/signUp.ts b/src/lib/resolvers/Mutation/signUp.ts new file mode 100644 index 0000000000..ca4aca8e3f --- /dev/null +++ b/src/lib/resolvers/Mutation/signUp.ts @@ -0,0 +1,92 @@ +import bcrypt from "bcryptjs"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Organization } from "../../models"; +import { + createAccessToken, + createRefreshToken, + uploadImage, + copyToClipboard, +} from "../../utilities"; +import { androidFirebaseOptions, iosFirebaseOptions } from "../../config"; + +export const signUp: MutationResolvers["signUp"] = async (_parent, args) => { + const userWithEmailExists = await User.exists({ + email: args.data.email.toLowerCase(), + }); + + if (userWithEmailExists === true) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? "Email already exists" + : requestContext.translate("email.alreadyExists"), + "email.alreadyExists", + "email" + ); + } + + // TODO: this check is to be removed + let organization; + if (args.data.organizationUserBelongsToId) { + organization = await Organization.findOne({ + _id: args.data.organizationUserBelongsToId, + }).lean(); + + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + } + + const hashedPassword = await bcrypt.hash(args.data.password, 12); + + // Upload file + let uploadImageObj; + if (args.file) { + uploadImageObj = await uploadImage(args.file, null); + } + + const createdUser = await User.create({ + ...args.data, + organizationUserBelongsTo: organization ? organization._id : null, + email: args.data.email.toLowerCase(), // ensure all emails are stored as lowercase to prevent duplicated due to comparison errors + image: uploadImageObj + ? uploadImageObj.imageAlreadyInDbPath + ? uploadImageObj.imageAlreadyInDbPath + : uploadImageObj.newImagePath + : null, + password: hashedPassword, + }); + + const accessToken = await createAccessToken(createdUser); + const refreshToken = await createRefreshToken(createdUser); + + copyToClipboard(`{ + "Authorization": "Bearer ${accessToken}" + }`); + + const filteredCreatedUser = createdUser.toObject(); + + // @ts-ignore + delete filteredCreatedUser.password; + + return { + user: filteredCreatedUser, + accessToken, + refreshToken, + androidFirebaseOptions, + iosFirebaseOptions, + }; +}; diff --git a/src/lib/resolvers/Mutation/unblockUser.ts b/src/lib/resolvers/Mutation/unblockUser.ts new file mode 100644 index 0000000000..024be95c8e --- /dev/null +++ b/src/lib/resolvers/Mutation/unblockUser.ts @@ -0,0 +1,106 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { adminCheck } from "../../utilities"; +import { + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { Organization, User } from "../../models"; + +export const unblockUser: MutationResolvers["unblockUser"] = async ( + _parent, + args, + context +) => { + const organization = await Organization.findOne({ + _id: args.organizationId, + }).lean(); + + // checks if there exists an organization with _id === args.organizationId + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // ensure user exists + const user = await User.findOne({ + _id: args.userId, + }).lean(); + + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // checks if current user is an admin of the organization with _id === args.organizationId + adminCheck(context.userId, organization); + + const userIsBlockedFromOrganization = organization.blockedUsers.some( + (blockedUser) => blockedUser.toString() === user._id.toString() + ); + + // checks if user with _id === args.userId is blocked by organzation with _id == args.organizationId + if (userIsBlockedFromOrganization === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // remove user from the blockedUsers list inside the organization record + await Organization.updateOne( + { + _id: organization._id, + }, + { + $set: { + blockedUsers: organization.blockedUsers.filter( + (blockedUser) => blockedUser !== user._id + ), + }, + } + ); + + // remove the organization from the organizationsBlockedBy array inside the user record + return await User.findOneAndUpdate( + { + _id: user._id, + }, + { + $set: { + organizationsBlockedBy: user.organizationsBlockedBy.filter( + (organizationBlockedBy) => organizationBlockedBy !== organization._id + ), + }, + }, + { + new: true, + } + ) + .select(["-password"]) + .lean(); +}; diff --git a/src/lib/resolvers/Mutation/unlikeComment.ts b/src/lib/resolvers/Mutation/unlikeComment.ts new file mode 100644 index 0000000000..2752c1e235 --- /dev/null +++ b/src/lib/resolvers/Mutation/unlikeComment.ts @@ -0,0 +1,73 @@ +import { + COMMENT_NOT_FOUND, + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_MESSAGE, + COMMENT_NOT_FOUND_PARAM, + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Comment } from "../../models"; + +export const unlikeComment: MutationResolvers["unlikeComment"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const comment = await Comment.findOne({ + _id: args.id, + }).lean(); + + if (!comment) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? COMMENT_NOT_FOUND + : requestContext.translate(COMMENT_NOT_FOUND_MESSAGE), + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_PARAM + ); + } + + const currentUserHasLikedComment = comment.likedBy.some( + (liker) => liker.toString() === context.userId.toString() + ); + + if (currentUserHasLikedComment === true) { + return await Comment.findOneAndUpdate( + { + _id: args.id, + }, + { + $pull: { + likedBy: context.userId, + }, + $inc: { + likeCount: -1, + }, + }, + { + new: true, + } + ).lean(); + } + + return comment; +}; diff --git a/src/lib/resolvers/Mutation/unlikePost.ts b/src/lib/resolvers/Mutation/unlikePost.ts new file mode 100644 index 0000000000..45933dc59a --- /dev/null +++ b/src/lib/resolvers/Mutation/unlikePost.ts @@ -0,0 +1,73 @@ +import { + IN_PRODUCTION, + POST_NOT_FOUND, + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_MESSAGE, + POST_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Post } from "../../models"; + +export const unlikePost: MutationResolvers["unlikePost"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const post = await Post.findOne({ + _id: args.id, + }).lean(); + + if (!post) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? POST_NOT_FOUND + : requestContext.translate(POST_NOT_FOUND_MESSAGE), + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_PARAM + ); + } + + const currentUserHasLikedPost = post.likedBy.some( + (liker) => liker.toString() === context.userId.toString() + ); + + if (currentUserHasLikedPost === true) { + return await Post.findOneAndUpdate( + { + _id: post._id, + }, + { + $pull: { + likedBy: context.userId, + }, + $inc: { + likeCount: -1, + }, + }, + { + new: true, + } + ).lean(); + } + + return post; +}; diff --git a/src/lib/resolvers/Mutation/unregisterForEventByUser.ts b/src/lib/resolvers/Mutation/unregisterForEventByUser.ts new file mode 100644 index 0000000000..b4d6114fdc --- /dev/null +++ b/src/lib/resolvers/Mutation/unregisterForEventByUser.ts @@ -0,0 +1,101 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Event } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_PARAM, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_MESSAGE, + USER_ALREADY_UNREGISTERED, + USER_ALREADY_UNREGISTERED_MESSAGE, + USER_ALREADY_UNREGISTERED_CODE, + USER_ALREADY_UNREGISTERED_PARAM, +} from "../../../constants"; + +export const unregisterForEventByUser: MutationResolvers["unregisterForEventByUser"] = + async (_parent, args, context) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // checks if current user exists + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const event = await Event.findOne({ + _id: args.id, + }).lean(); + + // checks if there exists an event with _id === args.id + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + // gets position(index) of current user's _id in the registrants list of event + const index = event.registrants.findIndex((element) => { + return String(element.userId) === String(context.userId); + }); + + // checks if current user is a registrant of event + if (index === -1) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + if (event.registrants[index].status === "ACTIVE") { + const updatedRegistrants = event.registrants; + updatedRegistrants[index] = { + id: updatedRegistrants[index].id, + userId: updatedRegistrants[index].userId, + user: updatedRegistrants[index].user, + status: "DELETED", + createdAt: updatedRegistrants[index].createdAt, + }; + + return await Event.findOneAndUpdate( + { + _id: args.id, + status: "ACTIVE", + }, + { + $set: { + registrants: updatedRegistrants, + }, + }, + { + new: true, + } + ).lean(); + } else { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_ALREADY_UNREGISTERED + : requestContext.translate(USER_ALREADY_UNREGISTERED_MESSAGE), + USER_ALREADY_UNREGISTERED_CODE, + USER_ALREADY_UNREGISTERED_PARAM + ); + } + }; diff --git a/src/lib/resolvers/Mutation/updateEvent.ts b/src/lib/resolvers/Mutation/updateEvent.ts new file mode 100644 index 0000000000..0e926a09bc --- /dev/null +++ b/src/lib/resolvers/Mutation/updateEvent.ts @@ -0,0 +1,82 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Event } from "../../models"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../../constants"; + +export const updateEvent: MutationResolvers["updateEvent"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // checks if current user exists + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const event = await Event.findOne({ + _id: args.id, + }).lean(); + + // checks if there exists an event with _id === args.id + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + const currentUserIsEventAdmin = event.admins.some( + (admin) => admin.toString() === context.userId.toString() + ); + + // checks if current user is an admin of the event with _id === args.id + if (currentUserIsEventAdmin === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + return await Event.findOneAndUpdate( + { + _id: args.id, + }, + // @ts-ignore + { + ...args.data, + }, + { + new: true, + } + ).lean(); +}; diff --git a/src/lib/resolvers/Mutation/updateEventProject.ts b/src/lib/resolvers/Mutation/updateEventProject.ts new file mode 100644 index 0000000000..b8db032e44 --- /dev/null +++ b/src/lib/resolvers/Mutation/updateEventProject.ts @@ -0,0 +1,74 @@ +import { User, EventProject } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + EVENT_NOT_FOUND_CODE, + EVENT_PROJECT_NOT_FOUND, + EVENT_PROJECT_NOT_FOUND_MESSAGE, + EVENT_PROJECT_NOT_FOUND_PARAM, + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const updateEventProject = async ( + _parent: any, + args: any, + context: any +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const eventProject = await EventProject.findOne({ + _id: args.id, + }).lean(); + + if (!eventProject) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_PROJECT_NOT_FOUND + : requestContext.translate(EVENT_PROJECT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_PROJECT_NOT_FOUND_PARAM + ); + } + + // toString() method converts mongodb's objectId to a javascript string for comparision + if (eventProject.creator.toString() !== context.userId.toString()) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + return await EventProject.findOneAndUpdate( + { + _id: args.id, + }, + { + ...args.data, + }, + { + new: true, + } + ).lean(); +}; diff --git a/src/lib/resolvers/Mutation/updateLanguage.ts b/src/lib/resolvers/Mutation/updateLanguage.ts new file mode 100644 index 0000000000..6cc2a84fab --- /dev/null +++ b/src/lib/resolvers/Mutation/updateLanguage.ts @@ -0,0 +1,45 @@ +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User } from "../../models"; + +export const updateLanguage: MutationResolvers["updateLanguage"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + // checks if current user exists + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + return await User.findOneAndUpdate( + { + _id: context.userId, + }, + { + $set: { + appLanguageCode: args.languageCode, + }, + }, + { + new: true, + } + ).lean(); +}; diff --git a/src/lib/resolvers/Mutation/updateOrganization.ts b/src/lib/resolvers/Mutation/updateOrganization.ts new file mode 100644 index 0000000000..9713030d77 --- /dev/null +++ b/src/lib/resolvers/Mutation/updateOrganization.ts @@ -0,0 +1,46 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { Organization } from "../../models"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; +import { adminCheck } from "../../utilities"; + +export const updateOrganization: MutationResolvers["updateOrganization"] = + async (_parent, args, context) => { + const organization = await Organization.findOne({ + _id: args.id, + }).lean(); + + // Checks if organization with _id === args.id exists. + if (!organization) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + // checks if the current user is an admin of the organization + adminCheck(context.userId, organization); + + return await Organization.findOneAndUpdate( + { + _id: organization._id, + }, + { + $set: { + ...args.data, + }, + }, + { + new: true, + } + ).lean(); + }; diff --git a/src/lib/resolvers/Mutation/updatePluginInstalledOrgs.ts b/src/lib/resolvers/Mutation/updatePluginInstalledOrgs.ts new file mode 100644 index 0000000000..f42731ad30 --- /dev/null +++ b/src/lib/resolvers/Mutation/updatePluginInstalledOrgs.ts @@ -0,0 +1,55 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { Plugin } from "../../models"; + +/** + * @name updatePluginInstalledOrgs + * @description updates the installedOrgs list of the specific plugin and adds or removes the current orgId from the list. + * @param {any} parent parent of current request + * @param {object} args payload provided with the request + * @param {any} context context of entire application + */ + +export const updatePluginInstalledOrgs: MutationResolvers["updatePluginInstalledOrgs"] = + async (_parent, args, _context) => { + const plugin = await Plugin.findOne({ + _id: args.id, + }).lean(); + + const organizationHasPluginInstalled = plugin?.installedOrgs.some( + (organization) => organization.toString() === args.orgId + ); + + /* + Remove args.orgId from installedOrgs ifplugin is already installed for + organization with _id === args.orgId + */ + if (organizationHasPluginInstalled === true) { + return await Plugin.findOneAndUpdate( + { + _id: args.id, + }, + { + $pull: { + installedOrgs: args.orgId, + }, + }, + { + new: true, + } + ).lean(); + } else { + return await Plugin.findOneAndUpdate( + { + _id: args.id, + }, + { + $push: { + installedOrgs: args.orgId, + }, + }, + { + new: true, + } + ).lean(); + } + }; diff --git a/src/lib/resolvers/Mutation/updatePluginStatus.ts b/src/lib/resolvers/Mutation/updatePluginStatus.ts new file mode 100644 index 0000000000..08c1ff574d --- /dev/null +++ b/src/lib/resolvers/Mutation/updatePluginStatus.ts @@ -0,0 +1,25 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { Plugin } from "../../models"; + +/** + * @name updatePluginStatus + * @description toggles the installStatus of the plugin + * @param {any} parent parent of current request + * @param {object} args payload provided with the request + * @param {any} context context of entire application + */ + +export const updatePluginStatus: MutationResolvers["updatePluginStatus"] = + async (_parent, args, _context) => { + return await Plugin.findOneAndUpdate( + { + _id: args.id, + }, + { + pluginInstallStatus: args.status, + }, + { + new: true, + } + ).lean(); + }; diff --git a/src/lib/resolvers/Mutation/updateTask.ts b/src/lib/resolvers/Mutation/updateTask.ts new file mode 100644 index 0000000000..abcbb4136c --- /dev/null +++ b/src/lib/resolvers/Mutation/updateTask.ts @@ -0,0 +1,73 @@ +import { + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User, Task } from "../../models"; + +export const updateTask: MutationResolvers["updateTask"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const task = await Task.findOne({ + _id: args.id, + }).lean(); + + if (!task) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? "Task not found" + : requestContext.translate("task.notFound"), + "task.notFound", + "task" + ); + } + + if (task.creator.toString() !== context.userId.toString()) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } + + // @ts-ignore + const updatedTask = await Task.findOneAndUpdate( + { + _id: task._id, + }, + { + ...args, + }, + { + new: true, + } + ).lean(); + + return updatedTask; +}; diff --git a/src/lib/resolvers/Mutation/updateUserProfile.ts b/src/lib/resolvers/Mutation/updateUserProfile.ts new file mode 100644 index 0000000000..d3ff1d68c5 --- /dev/null +++ b/src/lib/resolvers/Mutation/updateUserProfile.ts @@ -0,0 +1,91 @@ +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User } from "../../models"; +import { uploadImage } from "../../utilities"; + +export const updateUserProfile: MutationResolvers["updateUserProfile"] = async ( + _parent, + args, + context +) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + if (args.data!.email !== undefined) { + const userWithEmailExists = await User.exists({ + email: args.data?.email?.toLowerCase(), + }); + + if (userWithEmailExists === true) { + throw new errors.ConflictError( + IN_PRODUCTION !== true + ? "Email already exists" + : requestContext.translate("email.alreadyExists"), + "email.alreadyExists", + "email" + ); + } + } + + // Upload file + let uploadImageObj; + if (args.file) { + uploadImageObj = await uploadImage(args.file, null); + } + + // Update User + if (uploadImageObj) { + return await User.findOneAndUpdate( + { + _id: context.userId, + }, + { + $set: { + email: args.data?.email, + firstName: args.data?.firstName, + lastName: args.data?.lastName, + image: uploadImageObj.imageAlreadyInDbPath + ? uploadImageObj.imageAlreadyInDbPath + : uploadImageObj.newImagePath, + }, + }, + { + new: true, + } + ).lean(); + } else { + return await User.findOneAndUpdate( + { + _id: context.userId, + }, + { + $set: { + email: args.data?.email, + firstName: args.data?.firstName, + lastName: args.data?.lastName, + }, + }, + { + new: true, + } + ).lean(); + } +}; diff --git a/src/lib/resolvers/Mutation/updateUserType.ts b/src/lib/resolvers/Mutation/updateUserType.ts new file mode 100644 index 0000000000..172f304942 --- /dev/null +++ b/src/lib/resolvers/Mutation/updateUserType.ts @@ -0,0 +1,53 @@ +import { MutationResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { + USER_NOT_AUTHORIZED, + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { errors, requestContext } from "../../libraries"; + +export const updateUserType: MutationResolvers["updateUserType"] = async ( + _parent, + args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }) + .select(["userType"]) + .lean(); + + if (currentUser!.userType !== "SUPERADMIN") { + throw new Error(USER_NOT_AUTHORIZED); + } + + const userExists = await User.exists({ + _id: args.data.id!, + }); + + if (userExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + await User.updateOne( + { + _id: args.data.id!, + }, + { + userType: args.data.userType!, + adminApproved: true, + } + ); + + return true; +}; diff --git a/src/lib/resolvers/Organization/admins.ts b/src/lib/resolvers/Organization/admins.ts new file mode 100644 index 0000000000..e090901e74 --- /dev/null +++ b/src/lib/resolvers/Organization/admins.ts @@ -0,0 +1,10 @@ +import { User } from "../../models"; +import { OrganizationResolvers } from "../../../generated/graphqlCodegen"; + +export const admins: OrganizationResolvers["admins"] = async (parent) => { + return await User.find({ + _id: { + $in: parent.admins, + }, + }).lean(); +}; diff --git a/src/lib/resolvers/Organization/blockedUsers.ts b/src/lib/resolvers/Organization/blockedUsers.ts new file mode 100644 index 0000000000..b15ddd6a9f --- /dev/null +++ b/src/lib/resolvers/Organization/blockedUsers.ts @@ -0,0 +1,12 @@ +import { User } from "../../models"; +import { OrganizationResolvers } from "../../../generated/graphqlCodegen"; + +export const blockedUsers: OrganizationResolvers["blockedUsers"] = async ( + parent +) => { + return await User.find({ + _id: { + $in: parent.blockedUsers, + }, + }).lean(); +}; diff --git a/src/lib/resolvers/Organization/creator.ts b/src/lib/resolvers/Organization/creator.ts new file mode 100644 index 0000000000..e00a8b78c6 --- /dev/null +++ b/src/lib/resolvers/Organization/creator.ts @@ -0,0 +1,28 @@ +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { OrganizationResolvers } from "../../../generated/graphqlCodegen"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const creator: OrganizationResolvers["creator"] = async (parent) => { + const user = await User.findOne({ + _id: parent.creator, + }).lean(); + + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + return user; +}; diff --git a/src/lib/resolvers/Organization/index.ts b/src/lib/resolvers/Organization/index.ts new file mode 100644 index 0000000000..c7a6c1c42d --- /dev/null +++ b/src/lib/resolvers/Organization/index.ts @@ -0,0 +1,14 @@ +import { OrganizationResolvers } from "../../../generated/graphqlCodegen"; +import { admins } from "./admins"; +import { blockedUsers } from "./blockedUsers"; +import { creator } from "./creator"; +import { members } from "./members"; +import { membershipRequests } from "./membershipRequests"; + +export const Organization: OrganizationResolvers = { + admins, + blockedUsers, + creator, + members, + membershipRequests, +}; diff --git a/src/lib/resolvers/Organization/members.ts b/src/lib/resolvers/Organization/members.ts new file mode 100644 index 0000000000..44af794aaf --- /dev/null +++ b/src/lib/resolvers/Organization/members.ts @@ -0,0 +1,10 @@ +import { User } from "../../models"; +import { OrganizationResolvers } from "../../../generated/graphqlCodegen"; + +export const members: OrganizationResolvers["members"] = async (parent) => { + return await User.find({ + _id: { + $in: parent.members, + }, + }).lean(); +}; diff --git a/src/lib/resolvers/Organization/membershipRequests.ts b/src/lib/resolvers/Organization/membershipRequests.ts new file mode 100644 index 0000000000..6416be3fbf --- /dev/null +++ b/src/lib/resolvers/Organization/membershipRequests.ts @@ -0,0 +1,11 @@ +import { MembershipRequest } from "../../models"; +import { OrganizationResolvers } from "../../../generated/graphqlCodegen"; + +export const membershipRequests: OrganizationResolvers["membershipRequests"] = + async (parent) => { + return await MembershipRequest.find({ + _id: { + $in: parent.membershipRequests, + }, + }).lean(); + }; diff --git a/src/lib/resolvers/Query/checkAuth.ts b/src/lib/resolvers/Query/checkAuth.ts new file mode 100644 index 0000000000..e38538d28e --- /dev/null +++ b/src/lib/resolvers/Query/checkAuth.ts @@ -0,0 +1,35 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; + +export const checkAuth: QueryResolvers["checkAuth"] = async ( + _parent, + _args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }).lean(); + + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + return { + ...currentUser, + organizationsBlockedBy: [], + }; +}; diff --git a/src/lib/resolvers/Query/comments.ts b/src/lib/resolvers/Query/comments.ts new file mode 100644 index 0000000000..d1c6f3008f --- /dev/null +++ b/src/lib/resolvers/Query/comments.ts @@ -0,0 +1,10 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Comment } from "../../models"; + +export const comments: QueryResolvers["comments"] = async () => { + return await Comment.find() + .populate("creator", "-password") + .populate("post") + .populate("likedBy") + .lean(); +}; diff --git a/src/lib/resolvers/Query/commentsByPost.ts b/src/lib/resolvers/Query/commentsByPost.ts new file mode 100644 index 0000000000..29d26a7e75 --- /dev/null +++ b/src/lib/resolvers/Query/commentsByPost.ts @@ -0,0 +1,85 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { requestContext, errors } from "../../libraries"; +import { Comment, Organization } from "../../models"; +import { + COMMENT_NOT_FOUND, + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_MESSAGE, + COMMENT_NOT_FOUND_PARAM, + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, + POST_NOT_FOUND, + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_MESSAGE, + POST_NOT_FOUND_PARAM, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const commentsByPost: QueryResolvers["commentsByPost"] = async ( + _parent, + args, + _context +) => { + const comments = await Comment.find({ + post: args.id, + }) + .populate("creator", "-password") + .populate("post") + .populate("likedBy") + .lean(); + + // Throws error if comments list is empty. + if (comments.length === 0) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? COMMENT_NOT_FOUND + : requestContext.translate(COMMENT_NOT_FOUND_MESSAGE), + COMMENT_NOT_FOUND_CODE, + COMMENT_NOT_FOUND_PARAM + ); + } + + // Throws error if no user exists for comments[0].creator. + if (!comments[0].creator) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + // Throws error if no post exists for comments[0].post. + if (!comments[0].post) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? POST_NOT_FOUND + : requestContext.translate(POST_NOT_FOUND_MESSAGE), + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_PARAM + ); + } + // Throws error if no organization exists for comments[0].post.organization. + const organizationExists = await Organization.exists({ + _id: comments[0].post.organization, + }); + + if (organizationExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + return comments; +}; diff --git a/src/lib/resolvers/Query/directChatMessages.ts b/src/lib/resolvers/Query/directChatMessages.ts new file mode 100644 index 0000000000..0a32638e98 --- /dev/null +++ b/src/lib/resolvers/Query/directChatMessages.ts @@ -0,0 +1,7 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { DirectChatMessage } from "../../models"; + +export const directChatMessages: QueryResolvers["directChatMessages"] = + async () => { + return await DirectChatMessage.find().lean(); + }; diff --git a/src/lib/resolvers/Query/directChats.ts b/src/lib/resolvers/Query/directChats.ts new file mode 100644 index 0000000000..e42515618a --- /dev/null +++ b/src/lib/resolvers/Query/directChats.ts @@ -0,0 +1,6 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { DirectChat } from "../../models"; + +export const directChats: QueryResolvers["directChats"] = async () => { + return await DirectChat.find().lean(); +}; diff --git a/src/lib/resolvers/Query/directChatsByUserID.ts b/src/lib/resolvers/Query/directChatsByUserID.ts new file mode 100644 index 0000000000..bdc4a43cd0 --- /dev/null +++ b/src/lib/resolvers/Query/directChatsByUserID.ts @@ -0,0 +1,23 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { DirectChat } from "../../models"; +import { IN_PRODUCTION } from "../../../constants"; + +export const directChatsByUserID: QueryResolvers["directChatsByUserID"] = + async (_parent, args) => { + const directChats = await DirectChat.find({ + users: args.id, + }).lean(); + + if (directChats.length === 0) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? "DirectChats not found" + : requestContext.translate("directChats.notFound"), + "directChats.notFound", + "directChats" + ); + } + + return directChats; + }; diff --git a/src/lib/resolvers/Query/directChatsMessagesByChatID.ts b/src/lib/resolvers/Query/directChatsMessagesByChatID.ts new file mode 100644 index 0000000000..364c8de627 --- /dev/null +++ b/src/lib/resolvers/Query/directChatsMessagesByChatID.ts @@ -0,0 +1,29 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { DirectChatMessage } from "../../models"; +import { + IN_PRODUCTION, + CHAT_NOT_FOUND, + CHAT_NOT_FOUND_MESSAGE, + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const directChatsMessagesByChatID: QueryResolvers["directChatsMessagesByChatID"] = + async (_parent, args) => { + const directChatsMessages = await DirectChatMessage.find({ + directChatMessageBelongsTo: args.id, + }).lean(); + + if (directChatsMessages.length === 0) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? CHAT_NOT_FOUND + : requestContext.translate(CHAT_NOT_FOUND_MESSAGE), + CHAT_NOT_FOUND_CODE, + CHAT_NOT_FOUND_PARAM + ); + } + + return directChatsMessages; + }; diff --git a/src/lib/resolvers/Query/event.ts b/src/lib/resolvers/Query/event.ts new file mode 100644 index 0000000000..dff9c176ca --- /dev/null +++ b/src/lib/resolvers/Query/event.ts @@ -0,0 +1,33 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Event } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const event: QueryResolvers["event"] = async (_parent, args) => { + const event = await Event.findOne({ + _id: args.id, + status: "ACTIVE", + }) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + return event; +}; diff --git a/src/lib/resolvers/Query/events.ts b/src/lib/resolvers/Query/events.ts new file mode 100644 index 0000000000..2e3e1e2e79 --- /dev/null +++ b/src/lib/resolvers/Query/events.ts @@ -0,0 +1,109 @@ +import { + EventOrderByInput, + InputMaybe, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Event } from "../../models"; + +export const events: QueryResolvers["events"] = async (_parent, args) => { + const sort = getSort(args.orderBy); + + const events = await Event.find({ + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + return events; +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "title_ASC") { + return { + title: 1, + }; + } else if (orderBy === "title_DESC") { + return { + title: -1, + }; + } else if (orderBy === "description_ASC") { + return { + description: 1, + }; + } else if (orderBy === "description_DESC") { + return { + description: -1, + }; + } else if (orderBy === "startDate_ASC") { + return { + startDate: 1, + }; + } else if (orderBy === "startDate_DESC") { + return { + startDate: -1, + }; + } else if (orderBy === "endDate_ASC") { + return { + endDate: 1, + }; + } else if (orderBy === "endDate_DESC") { + return { + endDate: -1, + }; + } else if (orderBy === "allDay_ASC") { + return { + allDay: 1, + }; + } else if (orderBy === "allDay_DESC") { + return { + allDay: -1, + }; + } else if (orderBy === "startTime_ASC") { + return { + startTime: 1, + }; + } else if (orderBy === "startTime_DESC") { + return { + startTime: -1, + }; + } else if (orderBy === "endTime_ASC") { + return { + endTime: 1, + }; + } else if (orderBy === "endTime_DESC") { + return { + endTime: -1, + }; + } else if (orderBy === "recurrance_ASC") { + return { + recurrance: 1, + }; + } else if (orderBy === "recurrance_DESC") { + return { + recurrance: -1, + }; + } else if (orderBy === "location_ASC") { + return { + location: 1, + }; + } else { + return { + location: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/eventsByOrganization.ts b/src/lib/resolvers/Query/eventsByOrganization.ts new file mode 100644 index 0000000000..e899631b55 --- /dev/null +++ b/src/lib/resolvers/Query/eventsByOrganization.ts @@ -0,0 +1,119 @@ +import { + EventOrderByInput, + InputMaybe, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Event, Interface_UserAttende } from "../../models"; +import { STATUS_ACTIVE } from "../../../constants"; + +export const eventsByOrganization: QueryResolvers["eventsByOrganization"] = + async (_parent, args) => { + const sort = getSort(args.orderBy); + + const events = await Event.find({ + organization: args.id, + status: "ACTIVE", + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + events.forEach((event) => { + event.registrants = event.registrants.filter( + (registrant: Interface_UserAttende) => + registrant.status === STATUS_ACTIVE + ); + }); + + return events; + }; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "title_ASC") { + return { + title: 1, + }; + } else if (orderBy === "title_DESC") { + return { + title: -1, + }; + } else if (orderBy === "description_ASC") { + return { + description: 1, + }; + } else if (orderBy === "description_DESC") { + return { + description: -1, + }; + } else if (orderBy === "startDate_ASC") { + return { + startDate: 1, + }; + } else if (orderBy === "startDate_DESC") { + return { + startDate: -1, + }; + } else if (orderBy === "endDate_ASC") { + return { + endDate: 1, + }; + } else if (orderBy === "endDate_DESC") { + return { + endDate: -1, + }; + } else if (orderBy === "allDay_ASC") { + return { + allDay: 1, + }; + } else if (orderBy === "allDay_DESC") { + return { + allDay: -1, + }; + } else if (orderBy === "startTime_ASC") { + return { + startTime: 1, + }; + } else if (orderBy === "startTime_DESC") { + return { + startTime: -1, + }; + } else if (orderBy === "endTime_ASC") { + return { + endTime: 1, + }; + } else if (orderBy === "endTime_DESC") { + return { + endTime: -1, + }; + } else if (orderBy === "recurrance_ASC") { + return { + recurrance: 1, + }; + } else if (orderBy === "recurrance_DESC") { + return { + recurrance: -1, + }; + } else if (orderBy === "location_ASC") { + return { + location: 1, + }; + } else { + return { + location: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/getDonationById.ts b/src/lib/resolvers/Query/getDonationById.ts new file mode 100644 index 0000000000..25454cfae5 --- /dev/null +++ b/src/lib/resolvers/Query/getDonationById.ts @@ -0,0 +1,17 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Donation } from "../../models"; + +/** + * @name getDonationsById a GraphQL Query + * @description returns donation as a transaction that matches the provided Id property from database + */ +export const getDonationById: QueryResolvers["getDonationById"] = async ( + _parent, + args +) => { + const donation = await Donation.findOne({ + _id: args.id, + }).lean(); + + return donation!; +}; diff --git a/src/lib/resolvers/Query/getDonationByOrgId.ts b/src/lib/resolvers/Query/getDonationByOrgId.ts new file mode 100644 index 0000000000..bc75071941 --- /dev/null +++ b/src/lib/resolvers/Query/getDonationByOrgId.ts @@ -0,0 +1,15 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Donation } from "../../models"; + +/** + * @name getDonationByOrgId a GraphQL Query + * @description returns list of donations as a transactions that matches the provided orgId property from database + */ +export const getDonationByOrgId: QueryResolvers["getDonationByOrgId"] = async ( + _parent, + args +) => { + return await Donation.find({ + orgId: args.orgId, + }).lean(); +}; diff --git a/src/lib/resolvers/Query/getDonations.ts b/src/lib/resolvers/Query/getDonations.ts new file mode 100644 index 0000000000..3f8fedb9a4 --- /dev/null +++ b/src/lib/resolvers/Query/getDonations.ts @@ -0,0 +1,10 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Donation } from "../../models"; + +/** + * @name getPlugins a GraphQL Query + * @description returns list of donations as a transactions from database + */ +export const getDonations: QueryResolvers["getDonations"] = async () => { + return await Donation.find().lean(); +}; diff --git a/src/lib/resolvers/Query/getPlugins.ts b/src/lib/resolvers/Query/getPlugins.ts new file mode 100644 index 0000000000..7883390924 --- /dev/null +++ b/src/lib/resolvers/Query/getPlugins.ts @@ -0,0 +1,10 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Plugin } from "../../models"; + +/** + * @name getPlugins a GraphQL Query + * @description returns list of plugin from database + */ +export const getPlugins: QueryResolvers["getPlugins"] = async () => { + return await Plugin.find().lean(); +}; diff --git a/src/lib/resolvers/Query/getlanguage.ts b/src/lib/resolvers/Query/getlanguage.ts new file mode 100644 index 0000000000..355bb29ed5 --- /dev/null +++ b/src/lib/resolvers/Query/getlanguage.ts @@ -0,0 +1,28 @@ +import { QueryResolvers, Translation } from "../../../generated/graphqlCodegen"; +import { Language } from "../../models"; + +export const getlanguage: QueryResolvers["getlanguage"] = async ( + _parent, + args +) => { + const languages = await Language.find({ + "translation.lang_code": args.lang_code, + }).lean(); + + const filteredLanguages: Array = []; + + languages.forEach((language) => { + language.translation.forEach((languageModel) => { + if (languageModel.lang_code === args.lang_code) { + filteredLanguages.push({ + lang_code: languageModel.lang_code, + en_value: language.en, + translation: languageModel.value, + verified: languageModel.verified, + }); + } + }); + }); + + return filteredLanguages; +}; diff --git a/src/lib/resolvers/Query/groupChatMessages.ts b/src/lib/resolvers/Query/groupChatMessages.ts new file mode 100644 index 0000000000..d2b213d4e3 --- /dev/null +++ b/src/lib/resolvers/Query/groupChatMessages.ts @@ -0,0 +1,7 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { GroupChatMessage } from "../../models"; + +export const groupChatMessages: QueryResolvers["groupChatMessages"] = + async () => { + return await GroupChatMessage.find().lean(); + }; diff --git a/src/lib/resolvers/Query/groupChats.ts b/src/lib/resolvers/Query/groupChats.ts new file mode 100644 index 0000000000..367d1073cd --- /dev/null +++ b/src/lib/resolvers/Query/groupChats.ts @@ -0,0 +1,6 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { GroupChat } from "../../models"; + +export const groupChats: QueryResolvers["groupChats"] = async () => { + return await GroupChat.find().lean(); +}; diff --git a/src/lib/resolvers/Query/groups.ts b/src/lib/resolvers/Query/groups.ts new file mode 100644 index 0000000000..b24933953a --- /dev/null +++ b/src/lib/resolvers/Query/groups.ts @@ -0,0 +1,6 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Group } from "../../models"; + +export const groups: QueryResolvers["groups"] = async () => { + return await Group.find().lean(); +}; diff --git a/src/lib/resolvers/Query/index.ts b/src/lib/resolvers/Query/index.ts new file mode 100644 index 0000000000..dd3d9ae19b --- /dev/null +++ b/src/lib/resolvers/Query/index.ts @@ -0,0 +1,76 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { checkAuth } from "./checkAuth"; +import { comments } from "./comments"; +import { commentsByPost } from "./commentsByPost"; +import { directChatMessages } from "./directChatMessages"; +import { directChats } from "./directChats"; +import { directChatsByUserID } from "./directChatsByUserID"; +import { directChatsMessagesByChatID } from "./directChatsMessagesByChatID"; +import { event } from "./event"; +import { events } from "./events"; +import { eventsByOrganization } from "./eventsByOrganization"; +import { getDonationById } from "./getDonationById"; +import { getDonationByOrgId } from "./getDonationByOrgId"; +import { getDonations } from "./getDonations"; +import { getlanguage } from "./getlanguage"; +import { getPlugins } from "./getPlugins"; +import { groupChatMessages } from "./groupChatMessages"; +import { groupChats } from "./groupChats"; +import { groups } from "./groups"; +import { isUserRegister } from "./isUserRegister"; +import { me } from "./me"; +import { myLanguage } from "./myLanguage"; +import { organizations } from "./organizations"; +import { organizationsConnection } from "./organizationsConnection"; +import { organizationsMemberConnection } from "./organizationsMemberConnection"; +import { post } from "./post"; +import { posts } from "./posts"; +import { postsByOrganization } from "./postsByOrganization"; +import { postsByOrganizationConnection } from "./postsByOrganizationConnection"; +import { registeredEventsByUser } from "./registeredEventsByUser"; +import { registrantsByEvent } from "./registrantsByEvent"; +import { tasksByEvent } from "./tasksByEvent"; +import { tasksByUser } from "./tasksByUser"; +import { user } from "./user"; +import { userLanguage } from "./userLanguage"; +import { users } from "./users"; +import { usersConnection } from "./usersConnection"; + +export const Query: QueryResolvers = { + checkAuth, + comments, + commentsByPost, + directChatMessages, + directChats, + directChatsByUserID, + directChatsMessagesByChatID, + event, + events, + eventsByOrganization, + getDonationById, + getDonationByOrgId, + getDonations, + getlanguage, + getPlugins, + groupChatMessages, + groupChats, + groups, + isUserRegister, + me, + myLanguage, + organizations, + organizationsConnection, + organizationsMemberConnection, + post, + posts, + postsByOrganization, + postsByOrganizationConnection, + registeredEventsByUser, + registrantsByEvent, + tasksByEvent, + tasksByUser, + user, + userLanguage, + users, + usersConnection, +}; diff --git a/src/lib/resolvers/Query/isUserRegister.ts b/src/lib/resolvers/Query/isUserRegister.ts new file mode 100644 index 0000000000..bf613582bf --- /dev/null +++ b/src/lib/resolvers/Query/isUserRegister.ts @@ -0,0 +1,52 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Event } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const isUserRegister: QueryResolvers["isUserRegister"] = async ( + _parent, + args, + context +) => { + const event = await Event.findOne({ + _id: args.eventId, + status: "ACTIVE", + }) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + let isCurrentUserRegistered = false; + + for (const registrant of event.registrants) { + if ( + registrant.userId === context.userId && + registrant.status === "ACTIVE" + ) { + isCurrentUserRegistered = true; + break; + } + } + + return { + event, + isRegistered: isCurrentUserRegistered, + }; +}; diff --git a/src/lib/resolvers/Query/me.ts b/src/lib/resolvers/Query/me.ts new file mode 100644 index 0000000000..3e02a9992e --- /dev/null +++ b/src/lib/resolvers/Query/me.ts @@ -0,0 +1,37 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + USER_NOT_FOUND, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM, + IN_PRODUCTION, +} from "../../../constants"; + +// Resolver function for field 'me' of type 'Query' +export const me: QueryResolvers["me"] = async (_parent, _args, context) => { + const currentUser = await User.findOne({ + _id: context.userId, + }) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + return currentUser; +}; diff --git a/src/lib/resolvers/Query/myLanguage.ts b/src/lib/resolvers/Query/myLanguage.ts new file mode 100644 index 0000000000..7c62b56b8a --- /dev/null +++ b/src/lib/resolvers/Query/myLanguage.ts @@ -0,0 +1,34 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const myLanguage: QueryResolvers["myLanguage"] = async ( + _parent, + _args, + context +) => { + const currentUser = await User.findOne({ + _id: context.userId, + }) + .select(["appLanguageCode"]) + .lean(); + + if (!currentUser) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + return currentUser.appLanguageCode; +}; diff --git a/src/lib/resolvers/Query/organizations.ts b/src/lib/resolvers/Query/organizations.ts new file mode 100644 index 0000000000..8e26e5e312 --- /dev/null +++ b/src/lib/resolvers/Query/organizations.ts @@ -0,0 +1,67 @@ +import { + InputMaybe, + OrganizationOrderByInput, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Organization } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + ORGANIZATION_NOT_FOUND, + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_MESSAGE, + ORGANIZATION_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const organizations: QueryResolvers["organizations"] = async ( + _parent, + args +) => { + const sort = getSort(args.orderBy); + + if (args.id) { + const organizationFound = await Organization.find({ + _id: args.id, + }) + .sort(sort) + .lean(); + + if (!organizationFound[0]) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? ORGANIZATION_NOT_FOUND + : requestContext.translate(ORGANIZATION_NOT_FOUND_MESSAGE), + ORGANIZATION_NOT_FOUND_CODE, + ORGANIZATION_NOT_FOUND_PARAM + ); + } + + return organizationFound; + } else { + return await Organization.find().sort(sort).limit(100).lean(); + } +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { _id: 1 }; + } else if (orderBy === "id_DESC") { + return { _id: -1 }; + } else if (orderBy === "name_ASC") { + return { name: 1 }; + } else if (orderBy === "name_DESC") { + return { name: -1 }; + } else if (orderBy === "description_ASC") { + return { description: 1 }; + } else if (orderBy === "description_DESC") { + return { description: -1 }; + } else if (orderBy === "apiUrl_ASC") { + return { apiUrl: 1 }; + } else { + return { apiUrl: -1 }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/organizationsConnection.ts b/src/lib/resolvers/Query/organizationsConnection.ts new file mode 100644 index 0000000000..23ce75b44a --- /dev/null +++ b/src/lib/resolvers/Query/organizationsConnection.ts @@ -0,0 +1,267 @@ +import { + InputMaybe, + OrganizationOrderByInput, + OrganizationWhereInput, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Organization } from "../../models"; + +export const organizationsConnection: QueryResolvers["organizationsConnection"] = + async (_parent, args) => { + const inputArg = getInputArg(args.where); + const sort = getSort(args.orderBy); + + const organizations = await Organization.find(inputArg) + .sort(sort) + .limit(args.first!) + .skip(args.skip!) + .lean(); + + return organizations; + }; + +const getInputArg = (where: InputMaybe | undefined) => { + let inputArg = {}; + + if (where) { + // Returns provided id organizations + if (where.id) { + inputArg = { + ...inputArg, + _id: where.id, + }; + } + + // Returns all organizations other than provided id + if (where.id_not) { + inputArg = { + ...inputArg, + _id: { $ne: where.id_not }, + }; + } + + // Return organizations with id in the provided list + if (where.id_in) { + inputArg = { + ...inputArg, + _id: { $in: where.id_in }, + }; + } + + // Returns organizations not included in provided id list + if (where.id_not_in) { + inputArg = { + ...inputArg, + _id: { $nin: where.id_not_in }, + }; + } + + // Returns provided name organization + if (where.name) { + inputArg = { + ...inputArg, + name: where.name, + }; + } + + // Returns organizations with not that name + if (where.name_not) { + inputArg = { + ...inputArg, + name: { $ne: where.name_not }, + }; + } + + // Return organizations with the given list name + if (where.name_in) { + inputArg = { + ...inputArg, + name: { $in: where.name_in }, + }; + } + + // Returns organizations with name not in the provided list + if (where.name_not_in) { + inputArg = { + ...inputArg, + name: { $nin: where.name_not_in }, + }; + } + + // Returns organizations with name containing provided string + if (where.name_contains) { + inputArg = { + ...inputArg, + name: { $regex: where.name_contains, $options: "i" }, + }; + } + + // Returns organizations with name starts with that provided string + if (where.name_starts_with) { + const regexp = new RegExp("^" + where.name_starts_with); + inputArg = { + ...inputArg, + name: regexp, + }; + } + + // Returns description organizations + if (where.description) { + inputArg = { + ...inputArg, + description: where.description, + }; + } + + // Returns organizations with not that description + if (where.description_not) { + inputArg = { + ...inputArg, + description: { $ne: where.description_not }, + }; + } + + // Return organizations with description in provided list + if (where.description_in) { + inputArg = { + ...inputArg, + description: { $in: where.description_in }, + }; + } + + // Return organizations with description not in provided list + if (where.description_not_in) { + inputArg = { + ...inputArg, + description: { $nin: where.description_not_in }, + }; + } + + // Return organizations with description should containing provided string + if (where.description_contains) { + inputArg = { + ...inputArg, + description: { + $regex: where.description_contains, + $options: "i", + }, + }; + } + + // Returns organizations with description starting with provided string + if (where.description_starts_with) { + const regexp = new RegExp("^" + where.description_starts_with); + inputArg = { + ...inputArg, + description: regexp, + }; + } + + // Returns provided apiUrl organizations + if (where.apiUrl) { + inputArg = { + ...inputArg, + apiUrl: where.apiUrl, + }; + } + + // Returns organizations with not that provided apiUrl + if (where.apiUrl_not) { + inputArg = { + ...inputArg, + apiUrl: { $ne: where.apiUrl_not }, + }; + } + + // Organizations apiUrl falls in provided list + if (where.apiUrl_in) { + inputArg = { + ...inputArg, + apiUrl: { $in: where.apiUrl_in }, + }; + } + + // Return organizations apiUrl not falls in the list + if (where.apiUrl_not_in) { + inputArg = { + ...inputArg, + apiUrl: { $nin: where.apiUrl_not_in }, + }; + } + + // Return organizations with apiUrl containing provided string + if (where.apiUrl_contains) { + inputArg = { + ...inputArg, + apiUrl: { $regex: where.apiUrl_contains, $options: "i" }, + }; + } + + // Returns organizations with apiUrl starts with provided string + if (where.apiUrl_starts_with) { + const regexp = new RegExp("^" + where.apiUrl_starts_with); + inputArg = { + ...inputArg, + apiUrl: regexp, + }; + } + + // Returns organizations with provided visibleInSearch condition + if (where.visibleInSearch !== undefined) { + inputArg = { + ...inputArg, + visibleInSearch: where.visibleInSearch, + }; + } + + // Returns organizations with provided isPublic condition + if (where.isPublic !== undefined) { + inputArg = { + ...inputArg, + isPublic: where.isPublic, + }; + } + } + + return inputArg; +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "name_ASC") { + return { + name: 1, + }; + } else if (orderBy === "name_DESC") { + return { + name: -1, + }; + } else if (orderBy === "description_ASC") { + return { + description: 1, + }; + } else if (orderBy === "description_DESC") { + return { + description: -1, + }; + } else if (orderBy === "apiUrl_ASC") { + return { + apiUrl: 1, + }; + } else { + return { + apiUrl: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/organizationsMemberConnection.ts b/src/lib/resolvers/Query/organizationsMemberConnection.ts new file mode 100644 index 0000000000..cc32f00ffc --- /dev/null +++ b/src/lib/resolvers/Query/organizationsMemberConnection.ts @@ -0,0 +1,411 @@ +import { + InputMaybe, + QueryResolvers, + UserOrderByInput, + UserWhereInput, +} from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +// @ts-ignore +export const organizationsMemberConnection: QueryResolvers["organizationsMemberConnection"] = + async (_parent, args) => { + const inputArg = getInputArg(args.where); + const sort = getSort(args.orderBy); + + // Pagination based Options + let paginateOptions; + + if (args.first) { + if (args.skip === null) { + throw "Missing Skip parameter. Set it to either 0 or some other value"; + } + + paginateOptions = { + lean: true, + sort: sort, + pagination: true, + page: args.skip, + limit: args.first, + }; + } else { + paginateOptions = { + sort: sort, + pagination: false, + }; + } + + const usersModel = await User.paginate( + { + joinedOrganizations: { + _id: args.orgId, + }, + ...inputArg, + }, + { + ...paginateOptions, + select: ["-password"], + } + ); + + let users = {}; + + if (paginateOptions.pagination) { + if (args.skip === undefined) { + throw new Error("Skip parameter is missing"); + } + + users = usersModel.docs.map((user) => { + return { + ...user, + password: null, + }; + }); + } else { + users = usersModel.docs.map((user) => { + return { + ...user._doc, + password: null, + }; + }); + } + + return { + pageInfo: { + hasNextPage: usersModel.hasNextPage, + hasPreviousPage: usersModel.hasPrevPage, + totalPages: usersModel.totalPages, + nextPageNo: usersModel.nextPage, + prevPageNo: usersModel.prevPage, + currPageNo: usersModel.page, + }, + edges: users, + aggregate: { + count: usersModel.totalDocs, + }, + }; + }; + +const getInputArg = (where: InputMaybe | undefined) => { + let inputArg = {}; + + if (where) { + if (where.id) { + inputArg = { + ...inputArg, + _id: where.id, + }; + } + + //Returns all user other than provided id + if (where.id_not) { + inputArg = { + ...inputArg, + _id: { + $ne: where.id_not, + }, + }; + } + + //Return users with id in the provided list + if (where.id_in) { + inputArg = { + ...inputArg, + _id: { + $in: where.id_in, + }, + }; + } + + //Returns user not included in provided id list + if (where.id_not_in) { + inputArg = { + ...inputArg, + _id: { + $nin: where.id_not_in, + }, + }; + } + + //Returns provided firstName user + if (where.firstName) { + inputArg = { + ...inputArg, + firstName: where.firstName, + }; + } + + //Returns user with not that firstName + if (where.firstName_not) { + inputArg = { + ...inputArg, + firstName: { + $ne: where.firstName_not, + }, + }; + } + + //Return users with the given list firstName + if (where.firstName_in) { + inputArg = { + ...inputArg, + firstName: { + $in: where.firstName_in, + }, + }; + } + + //Returns users with firstName not in the provided list + if (where.firstName_not_in) { + inputArg = { + ...inputArg, + firstName: { + $nin: where.firstName_not_in, + }, + }; + } + + //Returns users with first name containing provided string + if (where.firstName_contains) { + inputArg = { + ...inputArg, + firstName: { + $regex: where.firstName_contains, + $options: "i", + }, + }; + } + + //Returns users with firstName starts with that provided string + if (where.firstName_starts_with) { + const regexp = new RegExp("^" + where.firstName_starts_with); + inputArg = { + ...inputArg, + firstName: regexp, + }; + } + + //Returns lastName user + if (where.lastName) { + inputArg = { + ...inputArg, + lastName: where.lastName, + }; + } + + //Returns user with not that lastName + if (where.lastName_not) { + inputArg = { + ...inputArg, + lastName: { + $ne: where.lastName_not, + }, + }; + } + + //Return users with lastName in provided list + if (where.lastName_in) { + inputArg = { + ...inputArg, + lastName: { + $in: where.lastName_in, + }, + }; + } + + //Return users with lastName not in provided list + if (where.lastName_not_in) { + inputArg = { + ...inputArg, + lastName: { + $nin: where.lastName_not_in, + }, + }; + } + + //Return users with lastName should containing provided string + if (where.lastName_contains) { + inputArg = { + ...inputArg, + lastName: { + $regex: where.lastName_contains, + $options: "i", + }, + }; + } + + //Returns users with LastName starting with provided string + if (where.lastName_starts_with) { + const regexp = new RegExp("^" + where.lastName_starts_with); + inputArg = { + ...inputArg, + lastName: regexp, + }; + } + + //Returns provided email user + if (where.email) { + inputArg = { + ...inputArg, + email: where.email, + }; + } + + //Returns user with not that provided email + if (where.email_not) { + inputArg = { + ...inputArg, + email: { + $ne: where.email_not, + }, + }; + } + + //User email falls in provided list + if (where.email_in) { + inputArg = { + ...inputArg, + email: { + $in: where.email_in, + }, + }; + } + + //Return User email not falls in the list + if (where.email_not_in) { + inputArg = { + ...inputArg, + email: { + $nin: where.email_not_in, + }, + }; + } + + //Return users with email containing provided string + if (where.email_contains) { + inputArg = { + ...inputArg, + email: { + $regex: where.email_contains, + $options: "i", + }, + }; + } + + //Returns user with email starts with provided string + if (where.email_starts_with) { + const regexp = new RegExp("^" + where.email_starts_with); + inputArg = { + ...inputArg, + email: regexp, + }; + } + + //Returns provided appLanguageCode user + if (where.appLanguageCode) { + inputArg = { + ...inputArg, + appLanguageCode: where.appLanguageCode, + }; + } + + //Returns user with not that provided appLanguageCode + if (where.appLanguageCode_not) { + inputArg = { + ...inputArg, + appLanguageCode: { + $ne: where.appLanguageCode_not, + }, + }; + } + + //User appLanguageCode falls in provided list + if (where.appLanguageCode_in) { + inputArg = { + ...inputArg, + appLanguageCode: { + $in: where.appLanguageCode_in, + }, + }; + } + + //Return User appLanguageCode not falls in the list + if (where.appLanguageCode_not_in) { + inputArg = { + ...inputArg, + appLanguageCode: { + $nin: where.appLanguageCode_not_in, + }, + }; + } + + //Return users with appLanguageCode containing provided string + if (where.appLanguageCode_contains) { + inputArg = { + ...inputArg, + appLanguageCode: { + $regex: where.appLanguageCode_contains, + $options: "i", + }, + }; + } + + //Returns user with appLanguageCode starts with provided string + if (where.appLanguageCode_starts_with) { + const regexp = new RegExp("^" + where.email_starts_with); + inputArg = { + ...inputArg, + appLanguageCode: regexp, + }; + } + } + + return inputArg; +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "firstName_ASC") { + return { + firstName: 1, + }; + } else if (orderBy === "firstName_DESC") { + return { + firstName: -1, + }; + } else if (orderBy === "lastName_ASC") { + return { + lastName: 1, + }; + } else if (orderBy === "lastName_DESC") { + return { + lastName: -1, + }; + } else if (orderBy === "appLanguageCode_ASC") { + return { + appLanguageCode: 1, + }; + } else if (orderBy === "appLanguageCode_DESC") { + return { + appLanguageCode: -1, + }; + } else if (orderBy === "email_ASC") { + return { + email: 1, + }; + } else { + return { + email: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/post.ts b/src/lib/resolvers/Query/post.ts new file mode 100644 index 0000000000..520986e544 --- /dev/null +++ b/src/lib/resolvers/Query/post.ts @@ -0,0 +1,39 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Post } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + POST_NOT_FOUND, + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_MESSAGE, + POST_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const post: QueryResolvers["post"] = async (_parent, args) => { + const post = await Post.findOne({ _id: args.id }) + .populate("organization") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("likedBy") + .populate("creator", "-password") + .lean(); + + if (!post) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? POST_NOT_FOUND + : requestContext.translate(POST_NOT_FOUND_MESSAGE), + POST_NOT_FOUND_CODE, + POST_NOT_FOUND_PARAM + ); + } + + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; +}; diff --git a/src/lib/resolvers/Query/posts.ts b/src/lib/resolvers/Query/posts.ts new file mode 100644 index 0000000000..65705e1cc6 --- /dev/null +++ b/src/lib/resolvers/Query/posts.ts @@ -0,0 +1,71 @@ +import { + InputMaybe, + PostOrderByInput, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Post } from "../../models"; + +export const posts: QueryResolvers["posts"] = async (_parent, args) => { + const sort = getSort(args.orderBy); + + let posts = await Post.find() + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + + posts = posts.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + return post; + }); + + return posts; +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { _id: 1 }; + } else if (orderBy === "id_DESC") { + return { _id: -1 }; + } else if (orderBy === "text_ASC") { + return { text: 1 }; + } else if (orderBy === "text_DESC") { + return { text: -1 }; + } else if (orderBy === "title_ASC") { + return { title: 1 }; + } else if (orderBy === "title_DESC") { + return { title: -1 }; + } else if (orderBy === "createdAt_ASC") { + return { createdAt: 1 }; + } else if (orderBy === "createdAt_DESC") { + return { createdAt: -1 }; + } else if (orderBy === "imageUrl_ASC") { + return { imageUrl: 1 }; + } else if (orderBy === "imageUrl_DESC") { + return { imageUrl: -1 }; + } else if (orderBy === "videoUrl_ASC") { + return { videoUrl: 1 }; + } else if (orderBy === "videoUrl_DESC") { + return { videoUrl: -1 }; + } else if (orderBy === "likeCount_ASC") { + return { likeCount: 1 }; + } else if (orderBy === "likeCount_DESC") { + return { likeCount: -1 }; + } else if (orderBy === "commentCount_ASC") { + return { commentCount: 1 }; + } else { + return { commentCount: -1 }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/postsByOrganization.ts b/src/lib/resolvers/Query/postsByOrganization.ts new file mode 100644 index 0000000000..cbb37ed421 --- /dev/null +++ b/src/lib/resolvers/Query/postsByOrganization.ts @@ -0,0 +1,98 @@ +import { + InputMaybe, + PostOrderByInput, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Post } from "../../models"; + +export const postsByOrganization: QueryResolvers["postsByOrganization"] = + async (_parent, args) => { + const sort = getSort(args.orderBy); + + return Post.find({ + organization: args.id, + }) + .sort(sort) + .populate("organization") + .populate("likedBy") + .populate({ + path: "comments", + populate: { + path: "creator", + }, + }) + .populate("creator", "-password") + .lean(); + }; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "text_ASC") { + return { + text: 1, + }; + } else if (orderBy === "text_DESC") { + return { + text: -1, + }; + } else if (orderBy === "title_ASC") { + return { + title: 1, + }; + } else if (orderBy === "title_DESC") { + return { + title: -1, + }; + } else if (orderBy === "createdAt_ASC") { + return { + createdAt: 1, + }; + } else if (orderBy === "createdAt_DESC") { + return { + createdAt: -1, + }; + } else if (orderBy === "imageUrl_ASC") { + return { + imageUrl: 1, + }; + } else if (orderBy === "imageUrl_DESC") { + return { + imageUrl: -1, + }; + } else if (orderBy === "videoUrl_ASC") { + return { + videoUrl: 1, + }; + } else if (orderBy === "videoUrl_DESC") { + return { + videoUrl: -1, + }; + } else if (orderBy === "likeCount_ASC") { + return { + likeCount: 1, + }; + } else if (orderBy === "likeCount_DESC") { + return { + likeCount: -1, + }; + } else if (orderBy === "commentCount_ASC") { + return { + commentCount: 1, + }; + } else { + return { + commentCount: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/postsByOrganizationConnection.ts b/src/lib/resolvers/Query/postsByOrganizationConnection.ts new file mode 100644 index 0000000000..5e12921625 --- /dev/null +++ b/src/lib/resolvers/Query/postsByOrganizationConnection.ts @@ -0,0 +1,307 @@ +import { + InputMaybe, + PostOrderByInput, + PostWhereInput, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Post } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { IN_PRODUCTION } from "../../../constants"; + +export const postsByOrganizationConnection: QueryResolvers["postsByOrganizationConnection"] = + async (_parent, args) => { + const sort = getSort(args.orderBy); + const inputArg = getInputArg(args.where); + + // Pagination based Options + let options = {}; + if (args.first) { + if (args.skip === null) { + throw new errors.ValidationError( + IN_PRODUCTION !== true + ? "Parameter is missing" + : requestContext.translate("parameter.missing"), + "parameter.missing" + ); + } + + options = { + lean: true, + sort: sort, + pagination: true, + page: args.skip, + limit: args.first, + populate: ["organization", "likedBy", "comments"], + }; + } else { + options = { + sort: sort, + pagination: false, + populate: ["organization", "likedBy", "comments"], + }; + } + + // Set of posts + const postsmodel = await Post.paginate( + { + organization: args.id, + ...inputArg, + }, + options + ); + + const posts = postsmodel.docs.map((post) => { + post.likeCount = post.likedBy.length || 0; + post.commentCount = post.comments.length || 0; + + return post; + }); + + return { + pageInfo: { + hasNextPage: postsmodel.hasNextPage, + hasPreviousPage: postsmodel.hasPrevPage, + totalPages: postsmodel.totalPages, + nextPageNo: postsmodel.nextPage, + prevPageNo: postsmodel.prevPage, + currPageNo: postsmodel.page, + }, + edges: posts, + aggregate: { + count: postsmodel.totalDocs, + }, + }; + }; + +const getInputArg = (where: InputMaybe | undefined) => { + let inputArg = {}; + + if (where) { + if (where.id) { + inputArg = { + ...inputArg, + _id: where.id, + }; + } + + //Returns all Posts other than provided id + if (where.id_not) { + inputArg = { + ...inputArg, + _id: { + $ne: where.id_not, + }, + }; + } + + //Return Posts with id in the provided list + if (where.id_in) { + inputArg = { + ...inputArg, + _id: { + $in: where.id_in, + }, + }; + } + + //Returns Posts not included in provided id list + if (where.id_not_in) { + inputArg = { + ...inputArg, + _id: { + $nin: where.id_not_in, + }, + }; + } + + //Returns provided text Posts + if (where.text) { + inputArg = { + ...inputArg, + text: where.text, + }; + } + + //Returns Posts with not the provided text + if (where.text_not) { + inputArg = { + ...inputArg, + text: { + $ne: where.text_not, + }, + }; + } + + //Return Posts with the given list text + if (where.text_in) { + inputArg = { + ...inputArg, + text: { + $in: where.text_in, + }, + }; + } + + //Returns Posts with text not in the provided list + if (where.text_not_in) { + inputArg = { + ...inputArg, + text: { + $nin: where.text_not_in, + }, + }; + } + + //Returns Posts with text containing provided string + if (where.text_contains) { + inputArg = { + ...inputArg, + text: { + $regex: where.text_contains, + $options: "i", + }, + }; + } + + //Returns Posts with text starts with that provided string + if (where.text_starts_with) { + const regexp = new RegExp("^" + where.text_starts_with); + inputArg = { + ...inputArg, + text: regexp, + }; + } + + //Returns provided title Posts + if (where.title) { + inputArg = { + ...inputArg, + title: where.title, + }; + } + + //Returns Posts with not that title + if (where.title_not) { + inputArg = { + ...inputArg, + title: { + $ne: where.title_not, + }, + }; + } + + //Return Posts with the given list title + if (where.title_in) { + inputArg = { + ...inputArg, + title: { + $in: where.title_in, + }, + }; + } + + //Returns Posts with title not in the provided list + if (where.title_not_in) { + inputArg = { + ...inputArg, + title: { + $nin: where.title_not_in, + }, + }; + } + + //Returns Posts with title containing provided string + if (where.title_contains) { + inputArg = { + ...inputArg, + title: { + $regex: where.title_contains, + $options: "i", + }, + }; + } + + //Returns Posts with title starts with that provided string + if (where.title_starts_with) { + const regexp = new RegExp("^" + where.title_starts_with); + inputArg = { + ...inputArg, + title: regexp, + }; + } + } + + return inputArg; +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "text_ASC") { + return { + text: 1, + }; + } else if (orderBy === "text_DESC") { + return { + text: -1, + }; + } else if (orderBy === "title_ASC") { + return { + title: 1, + }; + } else if (orderBy === "title_DESC") { + return { + title: -1, + }; + } else if (orderBy === "createdAt_ASC") { + return { + createdAt: 1, + }; + } else if (orderBy === "createdAt_DESC") { + return { + createdAt: -1, + }; + } else if (orderBy === "imageUrl_ASC") { + return { + imageUrl: 1, + }; + } else if (orderBy === "imageUrl_DESC") { + return { + imageUrl: -1, + }; + } else if (orderBy === "videoUrl_ASC") { + return { + videoUrl: 1, + }; + } else if (orderBy === "videoUrl_DESC") { + return { + videoUrl: -1, + }; + } else if (orderBy === "likeCount_ASC") { + return { + likeCount: 1, + }; + } else if (orderBy === "likeCount_DESC") { + return { + likeCount: -1, + }; + } else if (orderBy === "commentCount_ASC") { + return { + commentCount: 1, + }; + } else { + return { + commentCount: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/registeredEventsByUser.ts b/src/lib/resolvers/Query/registeredEventsByUser.ts new file mode 100644 index 0000000000..3da81b1b77 --- /dev/null +++ b/src/lib/resolvers/Query/registeredEventsByUser.ts @@ -0,0 +1,114 @@ +import { + EventOrderByInput, + InputMaybe, + QueryResolvers, +} from "../../../generated/graphqlCodegen"; +import { Event } from "../../models"; + +export const registeredEventsByUser: QueryResolvers["registeredEventsByUser"] = + async (_parent, args) => { + const sort = getSort(args.orderBy); + + return await Event.find({ + status: "ACTIVE", + registrants: { + $elemMatch: { + userId: args.id, + status: "ACTIVE", + }, + }, + }) + .sort(sort) + .populate("creator", "-password") + .populate("tasks") + .populate("admins", "-password") + .lean(); + }; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "title_ASC") { + return { + title: 1, + }; + } else if (orderBy === "title_DESC") { + return { + title: -1, + }; + } else if (orderBy === "description_ASC") { + return { + description: 1, + }; + } else if (orderBy === "description_DESC") { + return { + description: -1, + }; + } else if (orderBy === "startDate_ASC") { + return { + startDate: 1, + }; + } else if (orderBy === "startDate_DESC") { + return { + startDate: -1, + }; + } else if (orderBy === "endDate_ASC") { + return { + endDate: 1, + }; + } else if (orderBy === "endDate_DESC") { + return { + endDate: -1, + }; + } else if (orderBy === "allDay_ASC") { + return { + allDay: 1, + }; + } else if (orderBy === "allDay_DESC") { + return { + allDay: -1, + }; + } else if (orderBy === "startTime_ASC") { + return { + startTime: 1, + }; + } else if (orderBy === "startTime_DESC") { + return { + startTime: -1, + }; + } else if (orderBy === "endTime_ASC") { + return { + endTime: 1, + }; + } else if (orderBy === "endTime_DESC") { + return { + endTime: -1, + }; + } else if (orderBy === "recurrance_ASC") { + return { + recurrance: 1, + }; + } else if (orderBy === "recurrance_DESC") { + return { + recurrance: -1, + }; + } else if (orderBy === "location_ASC") { + return { + location: 1, + }; + } else { + return { + location: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/registrantsByEvent.ts b/src/lib/resolvers/Query/registrantsByEvent.ts new file mode 100644 index 0000000000..0a06996d6f --- /dev/null +++ b/src/lib/resolvers/Query/registrantsByEvent.ts @@ -0,0 +1,44 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { Event, Interface_User, Interface_UserAttende } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + EVENT_NOT_FOUND, + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_MESSAGE, + EVENT_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const registrantsByEvent: QueryResolvers["registrantsByEvent"] = async ( + _parent, + args +) => { + const event = await Event.findOne({ + _id: args.id, + status: "ACTIVE", + }) + .populate("registrants.user", "-password") + .lean(); + + if (!event) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? EVENT_NOT_FOUND + : requestContext.translate(EVENT_NOT_FOUND_MESSAGE), + EVENT_NOT_FOUND_CODE, + EVENT_NOT_FOUND_PARAM + ); + } + + const registrants: Array = []; + + if (event.registrants.length > 0) { + event.registrants.map((registrant: Interface_UserAttende) => { + if (registrant.status === "ACTIVE") { + registrants.push(registrant.user); + } + }); + } + + return registrants; +}; diff --git a/src/lib/resolvers/Query/tasksByEvent.ts b/src/lib/resolvers/Query/tasksByEvent.ts new file mode 100644 index 0000000000..4ea28d7b55 --- /dev/null +++ b/src/lib/resolvers/Query/tasksByEvent.ts @@ -0,0 +1,69 @@ +import { + InputMaybe, + QueryResolvers, + TaskOrderByInput, +} from "../../../generated/graphqlCodegen"; +import { Task } from "../../models"; + +export const tasksByEvent: QueryResolvers["tasksByEvent"] = async ( + _parent, + args +) => { + const sort = getSort(args.orderBy); + + return await Task.find({ + event: args.id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "title_ASC") { + return { + title: 1, + }; + } else if (orderBy === "title_DESC") { + return { + title: -1, + }; + } else if (orderBy === "description_ASC") { + return { + description: 1, + }; + } else if (orderBy === "description_DESC") { + return { + description: -1, + }; + } else if (orderBy === "createdAt_ASC") { + return { + createdAt: 1, + }; + } else if (orderBy === "createdAt_DESC") { + return { + createdAt: -1, + }; + } else if (orderBy === "deadline_ASC") { + return { + deadline: 1, + }; + } else { + return { + deadline: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/tasksByUser.ts b/src/lib/resolvers/Query/tasksByUser.ts new file mode 100644 index 0000000000..ddbe209736 --- /dev/null +++ b/src/lib/resolvers/Query/tasksByUser.ts @@ -0,0 +1,69 @@ +import { + InputMaybe, + QueryResolvers, + TaskOrderByInput, +} from "../../../generated/graphqlCodegen"; +import { Task } from "../../models"; + +export const tasksByUser: QueryResolvers["tasksByUser"] = async ( + _parent, + args +) => { + const sort = getSort(args.orderBy); + + return await Task.find({ + creator: args.id, + }) + .sort(sort) + .populate("event") + .populate("creator", "-password") + .lean(); +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "title_ASC") { + return { + title: 1, + }; + } else if (orderBy === "title_DESC") { + return { + title: -1, + }; + } else if (orderBy === "description_ASC") { + return { + description: 1, + }; + } else if (orderBy === "description_DESC") { + return { + description: -1, + }; + } else if (orderBy === "createdAt_ASC") { + return { + createdAt: 1, + }; + } else if (orderBy === "createdAt_DESC") { + return { + createdAt: -1, + }; + } else if (orderBy === "deadline_ASC") { + return { + deadline: 1, + }; + } else { + return { + deadline: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/user.ts b/src/lib/resolvers/Query/user.ts new file mode 100644 index 0000000000..52d583f83a --- /dev/null +++ b/src/lib/resolvers/Query/user.ts @@ -0,0 +1,38 @@ +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { errors, requestContext } from "../../libraries"; +import { User } from "../../models"; + +export const user: QueryResolvers["user"] = async (_parent, args, context) => { + const currentUserExists = await User.exists({ + _id: context.userId, + }); + + if (currentUserExists === false) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + const user = await User.findOne({ + _id: args.id, + }) + .populate("adminFor") + .lean(); + + // This Query field doesn't allow client to see organizations they are blocked by + return { + ...user!, + organizationsBlockedBy: [], + }; +}; diff --git a/src/lib/resolvers/Query/userLanguage.ts b/src/lib/resolvers/Query/userLanguage.ts new file mode 100644 index 0000000000..e29f4e46bc --- /dev/null +++ b/src/lib/resolvers/Query/userLanguage.ts @@ -0,0 +1,33 @@ +import { QueryResolvers } from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const userLanguage: QueryResolvers["userLanguage"] = async ( + _parent, + args +) => { + const user = await User.findOne({ + _id: args.userId, + }) + .select(["appLanguageCode"]) + .lean(); + + if (!user) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } + + return user.appLanguageCode; +}; diff --git a/src/lib/resolvers/Query/users.ts b/src/lib/resolvers/Query/users.ts new file mode 100644 index 0000000000..463fb69086 --- /dev/null +++ b/src/lib/resolvers/Query/users.ts @@ -0,0 +1,372 @@ +import { + InputMaybe, + QueryResolvers, + UserOrderByInput, + UserWhereInput, +} from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; +import { errors, requestContext } from "../../libraries"; +import { + IN_PRODUCTION, + USER_NOT_FOUND, + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_MESSAGE, + USER_NOT_FOUND_PARAM, +} from "../../../constants"; + +export const users: QueryResolvers["users"] = async (_parent, args) => { + const inputArg = getInputArg(args.where); + const sort = getSort(args.orderBy); + + const users = await User.find(inputArg) + .sort(sort) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + if (!users[0]) { + throw new errors.NotFoundError( + IN_PRODUCTION !== true + ? USER_NOT_FOUND + : requestContext.translate(USER_NOT_FOUND_MESSAGE), + USER_NOT_FOUND_CODE, + USER_NOT_FOUND_PARAM + ); + } else + return users.map((user) => { + return { + ...user, + organizationsBlockedBy: [], + }; + }); +}; + +const getInputArg = (where: InputMaybe | undefined) => { + let inputArg = {}; + + if (where) { + if (where.id) { + inputArg = { + ...inputArg, + _id: where.id, + }; + } + + //Returns all user other than provided id + if (where.id_not) { + inputArg = { + ...inputArg, + _id: { + $ne: where.id_not, + }, + }; + } + + //Return users with id in the provided list + if (where.id_in) { + inputArg = { + ...inputArg, + _id: { + $in: where.id_in, + }, + }; + } + + //Returns user not included in provided id list + if (where.id_not_in) { + inputArg = { + ...inputArg, + _id: { + $nin: where.id_not_in, + }, + }; + } + + //Returns provided firstName user + if (where.firstName) { + inputArg = { + ...inputArg, + firstName: where.firstName, + }; + } + + //Returns user with not that firstName + if (where.firstName_not) { + inputArg = { + ...inputArg, + firstName: { + $ne: where.firstName_not, + }, + }; + } + + //Return users with the given list firstName + if (where.firstName_in) { + inputArg = { + ...inputArg, + firstName: { + $in: where.firstName_in, + }, + }; + } + + //Returns users with firstName not in the provided list + if (where.firstName_not_in) { + inputArg = { + ...inputArg, + firstName: { + $nin: where.firstName_not_in, + }, + }; + } + + //Returns users with first name containing provided string + if (where.firstName_contains) { + inputArg = { + ...inputArg, + firstName: { + $regex: where.firstName_contains, + $options: "i", + }, + }; + } + + //Returns users with firstName starts with that provided string + if (where.firstName_starts_with) { + const regexp = new RegExp("^" + where.firstName_starts_with); + inputArg = { + ...inputArg, + firstName: regexp, + }; + } + + //Returns lastName user + if (where.lastName) { + inputArg = { + ...inputArg, + lastName: where.lastName, + }; + } + + //Returns user with not that lastName + if (where.lastName_not) { + inputArg = { + ...inputArg, + lastName: { + $ne: where.lastName_not, + }, + }; + } + + //Return users with lastName in provided list + if (where.lastName_in) { + inputArg = { + ...inputArg, + lastName: { + $in: where.lastName_in, + }, + }; + } + + //Return users with lastName not in provided list + if (where.lastName_not_in) { + inputArg = { + ...inputArg, + lastName: { + $nin: where.lastName_not_in, + }, + }; + } + + //Return users with lastName should containing provided string + if (where.lastName_contains) { + inputArg = { + ...inputArg, + lastName: { + $regex: where.lastName_contains, + $options: "i", + }, + }; + } + + //Returns users with LastName starting with provided string + if (where.lastName_starts_with) { + const regexp = new RegExp("^" + where.lastName_starts_with); + inputArg = { + ...inputArg, + lastName: regexp, + }; + } + + //Returns provided email user + if (where.email) { + inputArg = { + ...inputArg, + email: where.email, + }; + } + + //Returns user with not that provided email + if (where.email_not) { + inputArg = { + ...inputArg, + email: { + $ne: where.email_not, + }, + }; + } + + //User email falls in provided list + if (where.email_in) { + inputArg = { + ...inputArg, + email: { + $in: where.email_in, + }, + }; + } + + //Return User email not falls in the list + if (where.email_not_in) { + inputArg = { + ...inputArg, + email: { + $nin: where.email_not_in, + }, + }; + } + + //Return users with email containing provided string + if (where.email_contains) { + inputArg = { + ...inputArg, + email: { + $regex: where.email_contains, + $options: "i", + }, + }; + } + + //Returns user with email starts with provided string + if (where.email_starts_with) { + const regexp = new RegExp("^" + where.email_starts_with); + inputArg = { + ...inputArg, + email: regexp, + }; + } + + //Returns provided appLanguageCode user + if (where.appLanguageCode) { + inputArg = { + ...inputArg, + appLanguageCode: where.appLanguageCode, + }; + } + + //Returns user with not that provided appLanguageCode + if (where.appLanguageCode_not) { + inputArg = { + ...inputArg, + appLanguageCode: { + $ne: where.appLanguageCode_not, + }, + }; + } + + //User appLanguageCode falls in provided list + if (where.appLanguageCode_in) { + inputArg = { + ...inputArg, + appLanguageCode: { + $in: where.appLanguageCode_in, + }, + }; + } + + //Return User appLanguageCode not falls in the list + if (where.appLanguageCode_not_in) { + inputArg = { + ...inputArg, + appLanguageCode: { + $nin: where.appLanguageCode_not_in, + }, + }; + } + + //Return users with appLanguageCode containing provided string + if (where.appLanguageCode_contains) { + inputArg = { + ...inputArg, + appLanguageCode: { + $regex: where.appLanguageCode_contains, + $options: "i", + }, + }; + } + + //Returns user with appLanguageCode starts with provided string + if (where.appLanguageCode_starts_with) { + const regexp = new RegExp("^" + where.appLanguageCode_starts_with); + inputArg = { + ...inputArg, + appLanguageCode: regexp, + }; + } + } + + return inputArg; +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "firstName_ASC") { + return { + firstName: 1, + }; + } else if (orderBy === "firstName_DESC") { + return { + firstName: -1, + }; + } else if (orderBy === "lastName_ASC") { + return { + lastName: 1, + }; + } else if (orderBy === "lastName_DESC") { + return { + lastName: -1, + }; + } else if (orderBy === "appLanguageCode_ASC") { + return { + appLanguageCode: 1, + }; + } else if (orderBy === "appLanguageCode_DESC") { + return { + appLanguageCode: -1, + }; + } else if (orderBy === "email_ASC") { + return { + email: 1, + }; + } else { + return { + email: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Query/usersConnection.ts b/src/lib/resolvers/Query/usersConnection.ts new file mode 100644 index 0000000000..c309c61469 --- /dev/null +++ b/src/lib/resolvers/Query/usersConnection.ts @@ -0,0 +1,355 @@ +import { + InputMaybe, + QueryResolvers, + UserOrderByInput, + UserWhereInput, +} from "../../../generated/graphqlCodegen"; +import { User } from "../../models"; + +export const usersConnection: QueryResolvers["usersConnection"] = async ( + _parent, + args +) => { + const inputArg = getInputArg(args.where); + const sort = getSort(args.orderBy); + + const users = await User.find(inputArg) + .sort(sort) + .limit(args.first!) + .skip(args.skip!) + .select(["-password"]) + .populate("createdOrganizations") + .populate("createdEvents") + .populate("joinedOrganizations") + .populate("registeredEvents") + .populate("eventAdmin") + .populate("adminFor") + .lean(); + + return users; +}; + +const getInputArg = (where: InputMaybe | undefined) => { + let inputArg = {}; + + if (where) { + if (where.id) { + inputArg = { + ...inputArg, + _id: where.id, + }; + } + + //Returns all user other than provided id + if (where.id_not) { + inputArg = { + ...inputArg, + _id: { + $ne: where.id_not, + }, + }; + } + + //Return users with id in the provided list + if (where.id_in) { + inputArg = { + ...inputArg, + _id: { + $in: where.id_in, + }, + }; + } + + //Returns user not included in provided id list + if (where.id_not_in) { + inputArg = { + ...inputArg, + _id: { + $nin: where.id_not_in, + }, + }; + } + + //Returns provided firstName user + if (where.firstName) { + inputArg = { + ...inputArg, + firstName: where.firstName, + }; + } + + //Returns user with not that firstName + if (where.firstName_not) { + inputArg = { + ...inputArg, + firstName: { + $ne: where.firstName_not, + }, + }; + } + + //Return users with the given list firstName + if (where.firstName_in) { + inputArg = { + ...inputArg, + firstName: { + $in: where.firstName_in, + }, + }; + } + + //Returns users with firstName not in the provided list + if (where.firstName_not_in) { + inputArg = { + ...inputArg, + firstName: { + $nin: where.firstName_not_in, + }, + }; + } + + //Returns users with first name containing provided string + if (where.firstName_contains) { + inputArg = { + ...inputArg, + firstName: { + $regex: where.firstName_contains, + $options: "i", + }, + }; + } + + //Returns users with firstName starts with that provided string + if (where.firstName_starts_with) { + const regexp = new RegExp("^" + where.firstName_starts_with); + inputArg = { + ...inputArg, + firstName: regexp, + }; + } + + //Returns lastName user + if (where.lastName) { + inputArg = { + ...inputArg, + lastName: where.lastName, + }; + } + + //Returns user with not that lastName + if (where.lastName_not) { + inputArg = { + ...inputArg, + lastName: { + $ne: where.lastName_not, + }, + }; + } + + //Return users with lastName in provided list + if (where.lastName_in) { + inputArg = { + ...inputArg, + lastName: { + $in: where.lastName_in, + }, + }; + } + + //Return users with lastName not in provided list + if (where.lastName_not_in) { + inputArg = { + ...inputArg, + lastName: { + $nin: where.lastName_not_in, + }, + }; + } + + //Return users with lastName should containing provided string + if (where.lastName_contains) { + inputArg = { + ...inputArg, + lastName: { + $regex: where.lastName_contains, + $options: "i", + }, + }; + } + + //Returns users with LastName starting with provided string + if (where.lastName_starts_with) { + const regexp = new RegExp("^" + where.lastName_starts_with); + inputArg = { + ...inputArg, + lastName: regexp, + }; + } + + //Returns provided email user + if (where.email) { + inputArg = { + ...inputArg, + email: where.email, + }; + } + + //Returns user with not that provided email + if (where.email_not) { + inputArg = { + ...inputArg, + email: { + $ne: where.email_not, + }, + }; + } + + //User email falls in provided list + if (where.email_in) { + inputArg = { + ...inputArg, + email: { + $in: where.email_in, + }, + }; + } + + //Return User email not falls in the list + if (where.email_not_in) { + inputArg = { + ...inputArg, + email: { + $nin: where.email_not_in, + }, + }; + } + + //Return users with email containing provided string + if (where.email_contains) { + inputArg = { + ...inputArg, + email: { + $regex: where.email_contains, + $options: "i", + }, + }; + } + + //Returns user with email starts with provided string + if (where.email_starts_with) { + const regexp = new RegExp("^" + where.email_starts_with); + inputArg = { + ...inputArg, + email: regexp, + }; + } + + //Returns provided appLanguageCode user + if (where.appLanguageCode) { + inputArg = { + ...inputArg, + appLanguageCode: where.appLanguageCode, + }; + } + + //Returns user with not that provided appLanguageCode + if (where.appLanguageCode_not) { + inputArg = { + ...inputArg, + appLanguageCode: { + $ne: where.appLanguageCode_not, + }, + }; + } + + //User appLanguageCode falls in provided list + if (where.appLanguageCode_in) { + inputArg = { + ...inputArg, + appLanguageCode: { + $in: where.appLanguageCode_in, + }, + }; + } + + //Return User appLanguageCode not falls in the list + if (where.appLanguageCode_not_in) { + inputArg = { + ...inputArg, + appLanguageCode: { + $nin: where.appLanguageCode_not_in, + }, + }; + } + + //Return users with appLanguageCode containing provided string + if (where.appLanguageCode_contains) { + inputArg = { + ...inputArg, + appLanguageCode: { + $regex: where.appLanguageCode_contains, + $options: "i", + }, + }; + } + + //Returns user with appLanguageCode starts with provided string + if (where.appLanguageCode_starts_with) { + const regexp = new RegExp("^" + where.email_starts_with); + inputArg = { + ...inputArg, + appLanguageCode: regexp, + }; + } + } + + return inputArg; +}; + +const getSort = (orderBy: InputMaybe | undefined) => { + if (orderBy !== null) { + if (orderBy === "id_ASC") { + return { + _id: 1, + }; + } else if (orderBy === "id_DESC") { + return { + _id: -1, + }; + } else if (orderBy === "firstName_ASC") { + return { + firstName: 1, + }; + } else if (orderBy === "firstName_DESC") { + return { + firstName: -1, + }; + } else if (orderBy === "lastName_ASC") { + return { + lastName: 1, + }; + } else if (orderBy === "lastName_DESC") { + return { + lastName: -1, + }; + } else if (orderBy === "appLanguageCode_ASC") { + return { + appLanguageCode: 1, + }; + } else if (orderBy === "appLanguageCode_DESC") { + return { + appLanguageCode: -1, + }; + } else if (orderBy === "email_ASC") { + return { + email: 1, + }; + } else { + return { + email: -1, + }; + } + } + + return {}; +}; diff --git a/src/lib/resolvers/Subscription/directMessageChat.ts b/src/lib/resolvers/Subscription/directMessageChat.ts new file mode 100644 index 0000000000..b325e71e36 --- /dev/null +++ b/src/lib/resolvers/Subscription/directMessageChat.ts @@ -0,0 +1,15 @@ +import { withFilter } from "apollo-server-express"; +import { SubscriptionResolvers } from "../../../generated/graphqlCodegen"; + +const CHAT_CHANNEL = "CHAT_CHANNEL"; + +export const directMessageChat: SubscriptionResolvers["directMessageChat"] = { + // @ts-ignore + subscribe: withFilter( + (_parent, _args, context) => context.pubsub.asyncIterator(CHAT_CHANNEL), + + (payload) => { + return payload.directMessageChat; + } + ), +}; diff --git a/src/lib/resolvers/Subscription/index.ts b/src/lib/resolvers/Subscription/index.ts new file mode 100644 index 0000000000..d0dc24c0d2 --- /dev/null +++ b/src/lib/resolvers/Subscription/index.ts @@ -0,0 +1,10 @@ +import { SubscriptionResolvers } from "../../../generated/graphqlCodegen"; +import { directMessageChat } from "./directMessageChat"; +import { messageSentToDirectChat } from "./messageSentToDirectChat"; +import { messageSentToGroupChat } from "./messageSentToGroupChat"; + +export const Subscription: SubscriptionResolvers = { + directMessageChat, + messageSentToDirectChat, + messageSentToGroupChat, +}; diff --git a/src/lib/resolvers/Subscription/messageSentToDirectChat.ts b/src/lib/resolvers/Subscription/messageSentToDirectChat.ts new file mode 100644 index 0000000000..48c9ed0429 --- /dev/null +++ b/src/lib/resolvers/Subscription/messageSentToDirectChat.ts @@ -0,0 +1,22 @@ +import { withFilter } from "apollo-server-express"; +import { SubscriptionResolvers } from "../../../generated/graphqlCodegen"; + +const MESSAGE_SENT_TO_DIRECT_CHAT = "MESSAGE_SENT_TO_DIRECT_CHAT"; + +export const messageSentToDirectChat: SubscriptionResolvers["messageSentToDirectChat"] = + { + // @ts-ignore + subscribe: withFilter( + (_parent, _args, context) => + context.pubsub.asyncIterator([MESSAGE_SENT_TO_DIRECT_CHAT]), + + (payload, _variables, context) => { + const { currentUserId } = context.context; + + return ( + currentUserId === payload.messageSentToDirectChat.receiver || + currentUserId === payload.messageSentToDirectChat.sender + ); + } + ), + }; diff --git a/src/lib/resolvers/Subscription/messageSentToGroupChat.ts b/src/lib/resolvers/Subscription/messageSentToGroupChat.ts new file mode 100644 index 0000000000..64882f4eae --- /dev/null +++ b/src/lib/resolvers/Subscription/messageSentToGroupChat.ts @@ -0,0 +1,31 @@ +import { withFilter } from "apollo-server-express"; +import { SubscriptionResolvers } from "../../../generated/graphqlCodegen"; +import { GroupChat } from "../../models"; + +const MESSAGE_SENT_TO_GROUP_CHAT = "MESSAGE_SENT_TO_GROUP_CHAT"; + +export const messageSentToGroupChat: SubscriptionResolvers["messageSentToGroupChat"] = + { + // @ts-ignore + subscribe: withFilter( + (_parent, _args, context) => + context.pubsub.asyncIterator([MESSAGE_SENT_TO_GROUP_CHAT]), + + async (payload, _variables, context) => { + const { currentUserId } = context.context; + + const groupChatId = + payload.messageSentToGroupChat.groupChatMessageBelongsTo; + + const groupChat = await GroupChat.findOne({ + _id: groupChatId, + }).lean(); + + const currentUserIsGroupChatMember = groupChat!.users.some( + (user) => user.toString() === currentUserId.toString() + ); + + return currentUserIsGroupChatMember; + } + ), + }; diff --git a/src/lib/resolvers/index.ts b/src/lib/resolvers/index.ts new file mode 100644 index 0000000000..2cb5f766c8 --- /dev/null +++ b/src/lib/resolvers/index.ts @@ -0,0 +1,22 @@ +import { Resolvers } from "../../generated/graphqlCodegen"; +import { DirectChat } from "./DirectChat"; +import { DirectChatMessage } from "./DirectChatMessage"; +import { GroupChat } from "./GroupChat"; +import { GroupChatMessage } from "./GroupChatMessage"; +import { MembershipRequest } from "./MembershipRequest"; +import { Mutation } from "./Mutation"; +import { Organization } from "./Organization"; +import { Query } from "./Query"; +import { Subscription } from "./Subscription"; + +export const resolvers: Resolvers = { + DirectChat, + DirectChatMessage, + GroupChat, + GroupChatMessage, + MembershipRequest, + Mutation, + Organization, + Query, + Subscription, +}; diff --git a/src/lib/typeDefs/chats/chat.ts b/src/lib/typeDefs/chats/chat.ts new file mode 100644 index 0000000000..89bec49910 --- /dev/null +++ b/src/lib/typeDefs/chats/chat.ts @@ -0,0 +1,47 @@ +import { gql } from "apollo-server-core"; + +export const chat = gql` + type DirectChat { + _id: ID! + users: [User!]! + messages: [DirectChatMessage] + creator: User! + organization: Organization! + } + + type GroupChat { + _id: ID! + users: [User!]! + messages: [GroupChatMessage] + creator: User! + organization: Organization! + } + + type GroupChatMessage { + _id: ID! + groupChatMessageBelongsTo: GroupChat! + sender: User! + createdAt: String! + messageContent: String! + } + + type DirectChatMessage { + _id: ID! + directChatMessageBelongsTo: DirectChat! + sender: User! + receiver: User! + createdAt: String! + messageContent: String! + } + + input createChatInput { + userIds: [ID!]! + organizationId: ID! + } + + input createGroupChatInput { + userIds: [ID!]! + organizationId: ID! + title: String! + } +`; diff --git a/src/lib/typeDefs/chats/index.ts b/src/lib/typeDefs/chats/index.ts new file mode 100644 index 0000000000..0c5c13a989 --- /dev/null +++ b/src/lib/typeDefs/chats/index.ts @@ -0,0 +1,2 @@ +export * from "./chat"; +export * from "./message"; diff --git a/src/lib/typeDefs/chats/message.ts b/src/lib/typeDefs/chats/message.ts new file mode 100644 index 0000000000..022a2d83d6 --- /dev/null +++ b/src/lib/typeDefs/chats/message.ts @@ -0,0 +1,17 @@ +import { gql } from "apollo-server-core"; + +export const message = gql` + type MessageChat { + _id: ID! + sender: User! + receiver: User! + message: String! + languageBarrier: Boolean + createdAt: String! + } + + input MessageChatInput { + message: String! + receiver: ID! + } +`; diff --git a/src/lib/typeDefs/donation.ts b/src/lib/typeDefs/donation.ts new file mode 100644 index 0000000000..ca9cfb01f9 --- /dev/null +++ b/src/lib/typeDefs/donation.ts @@ -0,0 +1,13 @@ +import { gql } from "apollo-server-core"; + +export const donation = gql` + type Donation { + _id: ID! + userId: ID! + orgId: ID! + payPalId: String! + nameOfUser: String! + nameOfOrg: String! + amount: Float! + } +`; diff --git a/src/lib/typeDefs/event.ts b/src/lib/typeDefs/event.ts new file mode 100644 index 0000000000..8b13023c4f --- /dev/null +++ b/src/lib/typeDefs/event.ts @@ -0,0 +1,153 @@ +import { gql } from "apollo-server-core"; + +export const event = gql` + type Event { + _id: ID! + title: String! + description: String! + startDate: String! + endDate: String! + startTime: String + endTime: String + allDay: Boolean! + recurring: Boolean! + recurrance: Recurrance + isPublic: Boolean! + isRegisterable: Boolean! + location: String + latitude: Float + longitude: Float + organization: Organization + creator: User! + registrants: [UserAttende] + admins(adminId: ID): [User] + tasks: [Task] + status: Status! + } + + type EventRegistrants { + event: Event! + isRegistered: Boolean! + } + + type UserAttende { + _id: ID! + userId: String! + user: User! + status: Status! + createdAt: String + } + + input EventInput { + title: String! + description: String! + startDate: String! + endDate: String + startTime: String + endTime: String + allDay: Boolean! + recurring: Boolean! + recurrance: Recurrance + isPublic: Boolean! + isRegisterable: Boolean! + location: String + latitude: Float + longitude: Float + organizationId: ID! + } + + # type EventProject { + # _id: ID! + # title:String! + # description: String! + # event: Event! + # tasks: [Task] + # } + + type Task { + _id: ID! + title: String! + description: String + event: Event! + creator: User! + createdAt: String! + deadline: String + } + + input UpdateEventInput { + title: String + description: String + recurring: Boolean + recurrance: Recurrance + isPublic: Boolean + isRegisterable: Boolean + startDate: String + endDate: String + location: String + latitude: Float + longitude: Float + allDay: Boolean + startTime: String + endTime: String + } + + input TaskInput { + title: String! + description: String + deadline: String + } + + input UpdateTaskInput { + title: String + description: String + deadline: String + } + + enum EventOrderByInput { + id_ASC + id_DESC + title_ASC + title_DESC + description_ASC + description_DESC + startDate_ASC + startDate_DESC + endDate_ASC + endDate_DESC + allDay_ASC + allDay_DESC + startTime_ASC + startTime_DESC + endTime_ASC + endTime_DESC + recurrance_ASC + recurrance_DESC + location_ASC + location_DESC + } + + enum TaskOrderByInput { + id_ASC + id_DESC + title_ASC + title_DESC + description_ASC + description_DESC + createdAt_ASC + createdAt_DESC + deadline_ASC + deadline_DESC + } + + # input EventProjectInput { + # title:String! + # description: String! + # eventId: String + # } + + # input UpdateEventProjectInput { + # title:String + # description: String + # } + # +`; diff --git a/src/lib/typeDefs/index.ts b/src/lib/typeDefs/index.ts new file mode 100644 index 0000000000..d0a8e27e60 --- /dev/null +++ b/src/lib/typeDefs/index.ts @@ -0,0 +1,79 @@ +import { gql } from "apollo-server-express"; +import { chat, message } from "./chats"; +import { donation } from "./donation"; +import { event } from "./event"; +import { language } from "./language"; +import { mutation } from "./mutation"; +import { newsfeed } from "./newsfeed"; +import { organization } from "./organization"; +import { plugin, pluginField } from "./plugin"; +import { query } from "./query"; +import { user, auth } from "./user"; +import { utils } from "./utils"; + +/* +Named this additionalTypeDefs because they haven't yet been extracted into their own files. +*/ +const additionalTypeDefs = gql` + directive @auth on FIELD_DEFINITION + directive @role(requires: UserType) on FIELD_DEFINITION + + type Message { + _id: ID! + text: String + createdAt: String + imageUrl: String + videoUrl: String + creator: User + } + + input GroupInput { + title: String + description: String + organizationId: ID! + } + + type Group { + _id: ID + title: String + description: String + createdAt: String + organization: Organization! + admins: [User] + } + + type Subscription { + messageSentToDirectChat: DirectChatMessage + messageSentToGroupChat: GroupChatMessage + directMessageChat: MessageChat + } + + type DeletePayload { + success: Boolean! + } +`; + +/* +'gql' tag creates a value of type DocumentNode. Here typeDefs is an array of those DocumentNode type variables +that can be directly consumed by apollo-server. This is done to have our type-defintions defined inside +typescript files rather than .graphql files. Therefore, saving us the trouble of manually copying over those +.graphql files to the build directory during build time and also providing the benefits of dynamically altering +type-defintions using typescript. +*/ +export const typeDefs = [ + additionalTypeDefs, + auth, + chat, + donation, + event, + language, + mutation, + message, + newsfeed, + organization, + plugin, + pluginField, + query, + user, + utils, +]; diff --git a/src/lib/typeDefs/language.ts b/src/lib/typeDefs/language.ts new file mode 100644 index 0000000000..19ad1dac86 --- /dev/null +++ b/src/lib/typeDefs/language.ts @@ -0,0 +1,31 @@ +import { gql } from "apollo-server-core"; + +export const language = gql` + type Language { + _id: ID! + en: String! + translation: [LanguageModel] + createdAt: String! + } + + type LanguageModel { + _id: ID! + lang_code: String! + value: String! + verified: Boolean! + createdAt: String! + } + + input LanguageInput { + en_value: String! + translation_lang_code: String! + translation_value: String! + } + + type Translation { + lang_code: String + en_value: String + translation: String + verified: Boolean + } +`; diff --git a/src/lib/typeDefs/mutation.ts b/src/lib/typeDefs/mutation.ts new file mode 100644 index 0000000000..7585b276b2 --- /dev/null +++ b/src/lib/typeDefs/mutation.ts @@ -0,0 +1,164 @@ +import { gql } from "apollo-server-core"; + +export const mutation = gql` + type Mutation { + acceptAdmin(id: ID!): Boolean! @auth + + acceptMembershipRequest(membershipRequestId: ID!): MembershipRequest! @auth + + addLanguageTranslation(data: LanguageInput!): Language! @auth + + addOrganizationImage(file: Upload!, organizationId: String!): Organization! + @auth + + addUserImage(file: Upload!): User! @auth + + addUserToGroupChat(userId: ID!, chatId: ID!): GroupChat! @auth + + adminRemoveEvent(eventId: ID!): Event! @auth + + adminRemoveGroup(groupId: ID!): Message! @auth + + adminRemovePost(organizationId: ID!, postId: ID!): Post! @auth + + blockPluginCreationBySuperadmin(userId: ID!, blockUser: Boolean!): User! + @auth + + blockUser(organizationId: ID!, userId: ID!): User! @auth + + cancelMembershipRequest(membershipRequestId: ID!): MembershipRequest! @auth + + createAdmin(data: UserAndOrganizationInput!): User! @auth + + createComment(postId: ID!, data: CommentInput!): Comment @auth + + createDirectChat(data: createChatInput): DirectChat! @auth + + createDonation( + userId: ID! + orgId: ID! + payPalId: ID! + nameOfUser: String! + amount: Float! + nameOfOrg: String! + ): Donation! + + createEvent(data: EventInput): Event! @auth + + createGroup(data: GroupInput!): Group! @auth + + createGroupChat(data: createGroupChatInput): GroupChat! @auth + + createMessageChat(data: MessageChatInput!): MessageChat! @auth + + createOrganization(data: OrganizationInput, file: Upload): Organization! + @auth + + createPlugin( + pluginName: String! + pluginCreatedBy: String! + pluginDesc: String! + pluginInstallStatus: Boolean! + installedOrgs: [ID!] + ): Plugin! + + createPost(data: PostInput!, file: Upload): Post @auth + + createTask(data: TaskInput, eventId: ID!): Task! @auth + + deleteDonationById(id: ID!): DeletePayload! + + forgotPassword(data: ForgotPasswordData!): Boolean! + + joinPublicOrganization(organizationId: ID!): User! @auth + + leaveOrganization(organizationId: ID!): User! @auth + + likeComment(id: ID!): Comment @auth + + likePost(id: ID!): Post @auth + + login(data: LoginInput!): AuthData! + + logout: Boolean! @auth + + otp(data: OTPInput!): OtpData! + + recaptcha(data: RecaptchaVerification!): Boolean! + + refreshToken(refreshToken: String!): ExtendSession! + + registerForEvent(id: ID!): Event! @auth + + rejectAdmin(id: ID!): Boolean! @auth + + rejectMembershipRequest(membershipRequestId: ID!): MembershipRequest! @auth + + removeAdmin(data: UserAndOrganizationInput!): User! @auth + + removeComment(id: ID!): Comment @auth + + removeDirectChat(chatId: ID!, organizationId: ID!): DirectChat! @auth + + removeEvent(id: ID!): Event! @auth + + removeGroupChat(chatId: ID!): GroupChat! @auth + + removeMember(data: MultipleUsersAndOrganizationInput!): Organization! @auth + + removeOrganization(id: ID!): User! @auth + + removeOrganizationImage(organizationId: String!): Organization! @auth + + removePost(id: ID!): Post @auth + + removeTask(id: ID!): Task @auth + + removeUserFromGroupChat(userId: ID!, chatId: ID!): GroupChat! @auth + + removeUserImage: User! @auth + + revokeRefreshTokenForUser(userId: String!): Boolean! + + saveFcmToken(token: String): Boolean! @auth + + sendMembershipRequest(organizationId: ID!): MembershipRequest! @auth + + sendMessageToDirectChat( + chatId: ID! + messageContent: String! + ): DirectChatMessage! @auth + + sendMessageToGroupChat( + chatId: ID! + messageContent: String! + ): GroupChatMessage! @auth + + signUp(data: UserInput!, file: Upload): AuthData! + + unblockUser(organizationId: ID!, userId: ID!): User! @auth + + unlikeComment(id: ID!): Comment @auth + + unlikePost(id: ID!): Post @auth + + unregisterForEventByUser(id: ID!): Event! @auth + + updateEvent(id: ID!, data: UpdateEventInput): Event! @auth + + updateLanguage(languageCode: String!): User! @auth + + updateOrganization(id: ID!, data: UpdateOrganizationInput): Organization! + @auth + + updatePluginInstalledOrgs(id: ID!, orgId: ID!): Plugin! + + updatePluginStatus(id: ID!, status: Boolean!): Plugin! + + updateTask(id: ID!, data: UpdateTaskInput): Task @auth + + updateUserProfile(data: UpdateUserInput, file: Upload): User! @auth + + updateUserType(data: UpdateUserTypeInput!): Boolean! @auth + } +`; diff --git a/lib/schema/newsfeed/newsfeed.graphql b/src/lib/typeDefs/newsfeed.ts similarity index 83% rename from lib/schema/newsfeed/newsfeed.graphql rename to src/lib/typeDefs/newsfeed.ts index 563a558ce3..a19b1d9fab 100644 --- a/lib/schema/newsfeed/newsfeed.graphql +++ b/src/lib/typeDefs/newsfeed.ts @@ -1,17 +1,19 @@ -module.exports = ` +import { gql } from "apollo-server-core"; + +export const newsfeed = gql` type Post { _id: ID text: String! title: String createdAt: String imageUrl: String - videoUrl:String + videoUrl: String creator: User! organization: Organization! likedBy: [User] comments: [Comment] likeCount: Int - commentCount: Int + commentCount: Int } input PostWhereInput { @@ -37,14 +39,20 @@ module.exports = ` title_starts_with: String } - """A connection to a list of items.""" + """ + A connection to a list of items. + """ type PostConnection { - """Information to aid in pagination.""" + """ + Information to aid in pagination. + """ pageInfo: PageInfo! - """A list of edges.""" + """ + A list of edges. + """ edges: [Post]! - + aggregate: AggregatePost! } @@ -57,7 +65,7 @@ module.exports = ` text: String! title: String imageUrl: String - videoUrl:String + videoUrl: String organizationId: ID! } @@ -70,7 +78,7 @@ module.exports = ` likedBy: [User] likeCount: Int } - + input CommentInput { text: String! } @@ -93,4 +101,4 @@ module.exports = ` commentCount_ASC commentCount_DESC } -` \ No newline at end of file +`; diff --git a/lib/schema/organization/organization.graphql b/src/lib/typeDefs/organization.ts similarity index 75% rename from lib/schema/organization/organization.graphql rename to src/lib/typeDefs/organization.ts index 59615df6e2..000f29beae 100644 --- a/lib/schema/organization/organization.graphql +++ b/src/lib/typeDefs/organization.ts @@ -1,69 +1,63 @@ +import { gql } from "apollo-server-core"; - -module.exports = ` - - - +export const organization = gql` type Organization { - image:String + image: String _id: ID! - name:String! + name: String! description: String! location: String - isPublic: Boolean! + isPublic: Boolean! creator: User! members: [User] admins(adminId: ID): [User] membershipRequests: [MembershipRequest] blockedUsers: [User] visibleInSearch: Boolean! - apiUrl:String! - createdAt:String - tags: [String] + apiUrl: String! + createdAt: String + tags: [String!]! } type OrganizationInfoNode { - image:String + image: String _id: ID! - name:String! + name: String! description: String! - isPublic: Boolean! + isPublic: Boolean! creator: User! visibleInSearch: Boolean! - apiUrl:String! + apiUrl: String! + tags: [String!]! } input OrganizationInput { - name:String! + name: String! description: String! location: String attendees: String - isPublic: Boolean! + isPublic: Boolean! visibleInSearch: Boolean! - apiUrl:String - tags: [String] + apiUrl: String } - input UpdateOrganizationInput { - name:String + name: String description: String isPublic: Boolean visibleInSearch: Boolean } - - - input UserAndOrganizationInput{ - organizationId: ID!, userId: ID! + input UserAndOrganizationInput { + organizationId: ID! + userId: ID! } input MultipleUsersAndOrganizationInput { - organizationId: ID!, + organizationId: ID! userIds: [ID!]! } - type MembershipRequest { _id: ID! user: User! @@ -102,9 +96,9 @@ module.exports = ` visibleInSearch: Boolean isPublic: Boolean - } + } - enum OrganizationOrderByInput { + enum OrganizationOrderByInput { id_ASC id_DESC name_ASC @@ -113,6 +107,5 @@ module.exports = ` description_DESC apiUrl_ASC apiUrl_DESC - } - -` \ No newline at end of file + } +`; diff --git a/src/lib/typeDefs/plugin/index.ts b/src/lib/typeDefs/plugin/index.ts new file mode 100644 index 0000000000..99dff1328a --- /dev/null +++ b/src/lib/typeDefs/plugin/index.ts @@ -0,0 +1,2 @@ +export * from "./plugin"; +export * from "./pluginField"; diff --git a/src/lib/typeDefs/plugin/plugin.ts b/src/lib/typeDefs/plugin/plugin.ts new file mode 100644 index 0000000000..b9e13b2081 --- /dev/null +++ b/src/lib/typeDefs/plugin/plugin.ts @@ -0,0 +1,36 @@ +import { gql } from "apollo-server-core"; + +export const plugin = gql` + # type Plugin { + # orgId: Organization! + # pluginName: String! + # pluginKey: String + # pluginStatus: Status! + # pluginType: Type! + # additionalInfo: [PluginField!] + # createdAt: String + # } + + input PluginInput { + orgId: ID! + pluginName: String! + pluginKey: String + pluginType: Type + fields: [PluginFieldInput] + } + + input PluginFieldInput { + key: String! + value: String! + } + + # For Plugins + type Plugin { + _id: ID! + pluginName: String! + pluginCreatedBy: String! + pluginDesc: String! + pluginInstallStatus: Boolean! + installedOrgs: [ID!]! + } +`; diff --git a/src/lib/typeDefs/plugin/pluginField.ts b/src/lib/typeDefs/plugin/pluginField.ts new file mode 100644 index 0000000000..83a0282a29 --- /dev/null +++ b/src/lib/typeDefs/plugin/pluginField.ts @@ -0,0 +1,10 @@ +import { gql } from "apollo-server-core"; + +export const pluginField = gql` + type PluginField { + key: String! + value: String! + status: Status! + createdAt: String + } +`; diff --git a/lib/schema/query.graphql b/src/lib/typeDefs/query.ts similarity index 56% rename from lib/schema/query.graphql rename to src/lib/typeDefs/query.ts index aebe0a876f..0e7517f5f5 100644 --- a/lib/schema/query.graphql +++ b/src/lib/typeDefs/query.ts @@ -1,50 +1,103 @@ +import { gql } from "apollo-server-core"; - -module.exports = ` +export const query = gql` type Query { - me: User! @auth - user(id: ID!): User! @auth - users(where: UserWhereInput, orderBy: UserOrderByInput): [User] @auth - usersConnection(where: UserWhereInput, first: Int, skip: Int, orderBy: UserOrderByInput): [User]! @auth - + adminPlugin(orgId: ID!): [Plugin] + checkAuth: User! @auth - organizations(id: ID, orderBy: OrganizationOrderByInput): [Organization] - organizationsConnection(where: OrganizationWhereInput, first: Int, skip: Int, orderBy: OrganizationOrderByInput): [Organization]! - organizationsMemberConnection(orgId:ID!, where: UserWhereInput, first: Int, skip: Int, orderBy: UserOrderByInput): UserConnection! @auth - - isUserRegister(eventId: ID!): EventRegistrants + comments: [Comment] + + commentsByPost(id: ID!): [Comment] + + directChatMessages: [DirectChatMessage] + + directChats: [DirectChat] + + directChatsByUserID(id: ID!): [DirectChat] + + directChatsMessagesByChatID(id: ID!): [DirectChatMessage] + event(id: ID!): Event + events(id: ID, orderBy: EventOrderByInput): [Event] + eventsByOrganization(id: ID, orderBy: EventOrderByInput): [Event] - registeredEventsByUser(id: ID, orderBy: EventOrderByInput): [Event] - registrantsByEvent(id: ID!): [User] - + + getDonationById(id: ID!): Donation! + + getDonationByOrgId(orgId: ID!): [Donation] + + getDonations: [Donation] + + getlanguage(lang_code: String!): [Translation] + + getPlugins: [Plugin] + + groupChatMessages: [GroupChatMessage] + + groupChats: [GroupChat] + + groups: [Group] + + isUserRegister(eventId: ID!): EventRegistrants + + me: User! @auth + + myLanguage: String @auth + + organizations(id: ID, orderBy: OrganizationOrderByInput): [Organization] + + organizationsConnection( + where: OrganizationWhereInput + first: Int + skip: Int + orderBy: OrganizationOrderByInput + ): [Organization]! + + organizationsMemberConnection( + orgId: ID! + where: UserWhereInput + first: Int + skip: Int + orderBy: UserOrderByInput + ): UserConnection! @auth + + plugin(orgId: ID!): [Plugin] + + post(id: ID!): Post + posts(orderBy: PostOrderByInput): [Post] + postsByOrganization(id: ID!, orderBy: PostOrderByInput): [Post] - postsByOrganizationConnection(id: ID!, where: PostWhereInput, first: Int, skip: Int, orderBy: PostOrderByInput): PostConnection + + postsByOrganizationConnection( + id: ID! + where: PostWhereInput + first: Int + skip: Int + orderBy: PostOrderByInput + ): PostConnection + + registeredEventsByUser(id: ID, orderBy: EventOrderByInput): [Event] + + registrantsByEvent(id: ID!): [User] + tasksByEvent(id: ID!, orderBy: TaskOrderByInput): [Task] + tasksByUser(id: ID!, orderBy: TaskOrderByInput): [Task] - comments: [Comment] - commentsByPost(id: ID!): [Comment] - post(id: ID!): Post - groups: [Group] - - directChats: [DirectChat] - directChatMessages: [DirectChatMessage] - groupChats: [GroupChat] - groupChatMessages: [GroupChatMessage] - directChatsByUserID(id:ID!): [DirectChat] - directChatsMessagesByChatID(id:ID!):[DirectChatMessage] - myLanguage: String @auth + user(id: ID!): User! @auth + userLanguage(userId: ID!): String @auth - plugin(orgId: ID!): [Plugin] - adminPlugin(orgId: ID!): [Plugin] - getlanguage(lang_code: String!): [Translation] + users(where: UserWhereInput, orderBy: UserOrderByInput): [User] @auth - # For Plugins - getPlugins: [Plugin] + usersConnection( + where: UserWhereInput + first: Int + skip: Int + orderBy: UserOrderByInput + ): [User]! @auth } -` \ No newline at end of file +`; diff --git a/lib/schema/user/auth.graphql b/src/lib/typeDefs/user/auth.ts similarity index 59% rename from lib/schema/user/auth.graphql rename to src/lib/typeDefs/user/auth.ts index e0a8920ab3..19ae86ca4b 100644 --- a/lib/schema/user/auth.graphql +++ b/src/lib/typeDefs/user/auth.ts @@ -1,33 +1,31 @@ +import { gql } from "apollo-server-core"; - -module.exports = ` - - +export const auth = gql` input LoginInput { - email:String!, - password:String! + email: String! + password: String! } - + type AndroidFirebaseOptions { - apiKey: String, - appId: String, - messagingSenderId: String, - projectId: String, - storageBucket: String, + apiKey: String + appId: String + messagingSenderId: String + projectId: String + storageBucket: String } type IOSFirebaseOptions { - apiKey: String, - appId: String, - messagingSenderId: String, - projectId: String, - storageBucket: String, - iosClientId: String, - iosBundleId: String, + apiKey: String + appId: String + messagingSenderId: String + projectId: String + storageBucket: String + iosClientId: String + iosBundleId: String } type AuthData { - user: User!, + user: User! accessToken: String! refreshToken: String! androidFirebaseOptions: AndroidFirebaseOptions! @@ -56,4 +54,4 @@ module.exports = ` newPassword: String! otpToken: String! } -` \ No newline at end of file +`; diff --git a/src/lib/typeDefs/user/index.ts b/src/lib/typeDefs/user/index.ts new file mode 100644 index 0000000000..5e1b3abfe0 --- /dev/null +++ b/src/lib/typeDefs/user/index.ts @@ -0,0 +1,2 @@ +export * from "./auth"; +export * from "./user"; diff --git a/lib/schema/user/user.graphql b/src/lib/typeDefs/user/user.ts similarity index 59% rename from lib/schema/user/user.graphql rename to src/lib/typeDefs/user/user.ts index d2a91a6554..64fcc6a8d1 100644 --- a/lib/schema/user/user.graphql +++ b/src/lib/typeDefs/user/user.ts @@ -1,5 +1,6 @@ -module.exports = ` +import { gql } from "apollo-server-core"; +export const user = gql` type User { tokenVersion: Int! _id: ID! @@ -20,7 +21,7 @@ module.exports = ` organizationUserBelongsTo: Organization pluginCreationAllowed: Boolean adminApproved: Boolean - createdAt:String + createdAt: String } type UserConnection { @@ -55,41 +56,41 @@ module.exports = ` } input UserWhereInput { - id: ID - id_not: ID - id_in: [ID!] - id_not_in: [ID!] - id_contains: ID - id_starts_with: ID + id: ID + id_not: ID + id_in: [ID!] + id_not_in: [ID!] + id_contains: ID + id_starts_with: ID - firstName: String - firstName_not: String - firstName_in: [String!] - firstName_not_in: [String!] - firstName_contains: String - firstName_starts_with: String + firstName: String + firstName_not: String + firstName_in: [String!] + firstName_not_in: [String!] + firstName_contains: String + firstName_starts_with: String - lastName: String - lastName_not: String - lastName_in: [String!] - lastName_not_in: [String!] - lastName_contains: String - lastName_starts_with: String + lastName: String + lastName_not: String + lastName_in: [String!] + lastName_not_in: [String!] + lastName_contains: String + lastName_starts_with: String - email: String - email_not: String - email_in: [String!] - email_not_in: [String!] - email_contains: String - email_starts_with: String + email: String + email_not: String + email_in: [String!] + email_not_in: [String!] + email_contains: String + email_starts_with: String - appLanguageCode: String - appLanguageCode_not: String - appLanguageCode_in: [String!] - appLanguageCode_not_in: [String!] - appLanguageCode_contains: String - appLanguageCode_starts_with: String - } + appLanguageCode: String + appLanguageCode_not: String + appLanguageCode_in: [String!] + appLanguageCode_not_in: [String!] + appLanguageCode_contains: String + appLanguageCode_starts_with: String + } enum UserOrderByInput { id_ASC @@ -103,5 +104,4 @@ module.exports = ` appLanguageCode_ASC appLanguageCode_DESC } - -` \ No newline at end of file +`; diff --git a/src/lib/typeDefs/utils.ts b/src/lib/typeDefs/utils.ts new file mode 100644 index 0000000000..d3ca06a1a9 --- /dev/null +++ b/src/lib/typeDefs/utils.ts @@ -0,0 +1,46 @@ +import { gql } from "apollo-server-core"; + +export const utils = gql` + """ + Information about pagination in a connection. + """ + type PageInfo { + """ + When paginating forwards, are there more items? + """ + hasNextPage: Boolean! + + """ + When paginating backwards, are there more items? + """ + hasPreviousPage: Boolean! + totalPages: Int + nextPageNo: Int + prevPageNo: Int + currPageNo: Int + } + + enum Status { + ACTIVE + BLOCKED + DELETED + } + + enum UserType { + USER + ADMIN + SUPERADMIN + } + + enum Recurrance { + DAILY + WEEKLY + MONTHLY + YEARLY + ONCE + } + enum Type { + UNIVERSAL + PRIVATE + } +`; diff --git a/src/lib/utilities/adminCheck.ts b/src/lib/utilities/adminCheck.ts new file mode 100644 index 0000000000..73f291c59f --- /dev/null +++ b/src/lib/utilities/adminCheck.ts @@ -0,0 +1,29 @@ +import { Types } from "mongoose"; +import { errors, requestContext } from "../libraries"; +import { + IN_PRODUCTION, + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, +} from "../../constants"; +import { Interface_Organization } from "../models"; + +export const adminCheck = ( + userId: string | Types.ObjectId, + organization: Interface_Organization +) => { + const userIsOrganizationAdmin = organization.admins.some( + (admin) => admin.toString() === userId.toString() + ); + + if (userIsOrganizationAdmin === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } +}; diff --git a/src/lib/utilities/auth.ts b/src/lib/utilities/auth.ts new file mode 100644 index 0000000000..d8800330df --- /dev/null +++ b/src/lib/utilities/auth.ts @@ -0,0 +1,42 @@ +import jwt from "jsonwebtoken"; +import { Interface_User } from "../models"; + +export interface Interface_JwtTokenPayload { + tokenVersion: number; + userId: string; + firstName: string; + lastName: string; + email: string; +} + +export const createAccessToken = async (user: Interface_User) => { + return jwt.sign( + { + tokenVersion: user.tokenVersion, + userId: user._id.toString(), + firstName: user.firstName, + lastName: user.lastName, + email: user.email, + }, + process.env.ACCESS_TOKEN_SECRET!, + { + expiresIn: "15m", + } + ); +}; + +export const createRefreshToken = async (user: Interface_User) => { + return jwt.sign( + { + tokenVersion: user.tokenVersion, + userId: user._id.toString(), + firstName: user.firstName, + lastName: user.lastName, + email: user.email, + }, + process.env.REFRESH_TOKEN_SECRET!, + { + expiresIn: "30d", + } + ); +}; diff --git a/src/lib/utilities/copyToClipboard.ts b/src/lib/utilities/copyToClipboard.ts new file mode 100644 index 0000000000..cdbb8cc21b --- /dev/null +++ b/src/lib/utilities/copyToClipboard.ts @@ -0,0 +1,9 @@ +import ncp from "copy-paste"; +import { IN_PRODUCTION } from "../../constants"; + +export const copyToClipboard = (text: string) => { + // Only copies in development or test mode + if (IN_PRODUCTION !== true) { + ncp.copy(text); + } +}; diff --git a/src/lib/utilities/creatorCheck.ts b/src/lib/utilities/creatorCheck.ts new file mode 100644 index 0000000000..c9f0676cfa --- /dev/null +++ b/src/lib/utilities/creatorCheck.ts @@ -0,0 +1,27 @@ +import { errors, requestContext } from "../libraries"; +import { + USER_NOT_AUTHORIZED, + USER_NOT_AUTHORIZED_MESSAGE, + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM, + IN_PRODUCTION, +} from "../../constants"; +import { Types } from "mongoose"; +import { Interface_Organization } from "../models"; + +export const creatorCheck = ( + userId: string | Types.ObjectId, + organization: Interface_Organization +) => { + const userIsCreator = userId.toString() === organization.creator.toString(); + + if (userIsCreator === false) { + throw new errors.UnauthorizedError( + IN_PRODUCTION !== true + ? USER_NOT_AUTHORIZED + : requestContext.translate(USER_NOT_AUTHORIZED_MESSAGE), + USER_NOT_AUTHORIZED_CODE, + USER_NOT_AUTHORIZED_PARAM + ); + } +}; diff --git a/src/lib/utilities/deleteDuplicatedImage.ts b/src/lib/utilities/deleteDuplicatedImage.ts new file mode 100644 index 0000000000..53af24b295 --- /dev/null +++ b/src/lib/utilities/deleteDuplicatedImage.ts @@ -0,0 +1,13 @@ +import { unlink, PathLike } from "fs"; +import { logger } from "../libraries"; + +export const deleteDuplicatedImage = (imagePath: PathLike) => { + unlink(imagePath, function (error) { + if (error) { + throw error; + } + + // if no error is thrown, file has been deleted successfully + logger.info("File was deleted as it already exists in the db!"); + }); +}; diff --git a/src/lib/utilities/deleteImage.ts b/src/lib/utilities/deleteImage.ts new file mode 100644 index 0000000000..77ca4db98a --- /dev/null +++ b/src/lib/utilities/deleteImage.ts @@ -0,0 +1,55 @@ +import { unlink } from "fs"; +import { logger } from "../libraries"; +import { ImageHash } from "../models"; +import { reuploadDuplicateCheck } from "./reuploadDuplicateCheck"; + +export const deleteImage = async ( + imageToBeDeleted: string, + imageBelongingToItem?: string +) => { + let imageIsDuplicate = false; + + if (imageBelongingToItem) { + imageIsDuplicate = await reuploadDuplicateCheck( + imageToBeDeleted, + imageBelongingToItem + ); + } + + if (imageIsDuplicate === false) { + /* + Only remove the old image if its different from the new one + Ensure image hash isn't used by multiple users/organization before deleting it + */ + const imageHash = await ImageHash.findOne({ + fileName: imageToBeDeleted, + }).lean(); + + if (imageHash && imageHash.numberOfUses > 1) { + // Image can only be deleted if imageHash.numberOfUses === 1 + logger.info("Image cannot be deleted"); + } else { + logger.info("Image is only used once and therefore can be deleted"); + + unlink(imageToBeDeleted, (error) => { + if (error) { + throw error; + } + + // If no error occurs image has been successfully deleted. + logger.info("File deleted!"); + }); + } + + await ImageHash.updateOne( + { + fileName: imageToBeDeleted, + }, + { + $inc: { + numberOfUses: -1, + }, + } + ); + } +}; diff --git a/src/lib/utilities/imageAlreadyInDbCheck.ts b/src/lib/utilities/imageAlreadyInDbCheck.ts new file mode 100644 index 0000000000..ea1787d1d3 --- /dev/null +++ b/src/lib/utilities/imageAlreadyInDbCheck.ts @@ -0,0 +1,81 @@ +import { imageHash } from "image-hash"; +import { ImageHash } from "../models"; +import { deleteDuplicatedImage } from "./deleteDuplicatedImage"; +import { reuploadDuplicateCheck } from "./reuploadDuplicateCheck"; +import { errors, requestContext } from "../libraries"; + +/* +Check to see if image already exists in db using hash +if its there point to that image and remove the image just uploaded +if its not there allow the file to remain uploaded +*/ +export const imageAlreadyInDbCheck = async ( + oldImagePath: string | null, + newImagePath: string +) => { + try { + let fileName; + + const getImageHash = (): Promise => + new Promise((resolve, reject) => { + imageHash(`./${newImagePath}`, 16, true, (error: any, data: any) => { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + }); + + const hash = await getImageHash(); + + const existingImageHash = await ImageHash.findOne({ + hashValue: hash, + }).lean(); + + if (!existingImageHash) { + await ImageHash.create({ + hashValue: hash, + fileName: newImagePath, + numberOfUses: 1, + }); + } else { + const imageIsDuplicate = await reuploadDuplicateCheck( + oldImagePath, + newImagePath + ); + + if (imageIsDuplicate === false) { + // dont increment if the same user/org is using the same image multiple times for the same use case + await ImageHash.updateOne( + { + // Increase the number of places this image is used + hashValue: hash, + }, + { + $inc: { + numberOfUses: 1, + }, + } + ); + } + + deleteDuplicatedImage(newImagePath); + + fileName = existingImageHash.fileName; // will include have file already in db if pic is already saved will be null otherwise + } + + return fileName; + } catch (error) { + throw new errors.ValidationError( + [ + { + message: requestContext.translate("invalid.fileType"), + code: "invalid.fileType", + param: "fileType", + }, + ], + requestContext.translate("invalid.fileType") + ); + } +}; diff --git a/src/lib/utilities/imageExtensionCheck.ts b/src/lib/utilities/imageExtensionCheck.ts new file mode 100644 index 0000000000..3fa4eaa98b --- /dev/null +++ b/src/lib/utilities/imageExtensionCheck.ts @@ -0,0 +1,25 @@ +import { deleteImage } from "./deleteImage"; +import { errors, requestContext } from "../libraries"; + +export const imageExtensionCheck = async (filename: string) => { + const fileExtension = filename.split(".").pop(); + + if ( + fileExtension !== "png" && + fileExtension !== "jpg" && + fileExtension !== "jpeg" + ) { + await deleteImage(filename); + + throw new errors.ValidationError( + [ + { + message: requestContext.translate("invalid.fileType"), + code: "invalid.fileType", + param: "fileType", + }, + ], + requestContext.translate("invalid.fileType") + ); + } +}; diff --git a/src/lib/utilities/index.ts b/src/lib/utilities/index.ts new file mode 100644 index 0000000000..8449a02e94 --- /dev/null +++ b/src/lib/utilities/index.ts @@ -0,0 +1,7 @@ +export * from "./adminCheck"; +export * from "./auth"; +export * from "./copyToClipboard"; +export * from "./creatorCheck"; +export * from "./deleteImage"; +export * from "./mailer"; +export * from "./uploadImage"; diff --git a/src/lib/utilities/mailer.ts b/src/lib/utilities/mailer.ts new file mode 100644 index 0000000000..1009da1aa5 --- /dev/null +++ b/src/lib/utilities/mailer.ts @@ -0,0 +1,36 @@ +import nodemailer from "nodemailer"; +import { ERROR_IN_SENDING_MAIL } from "../../constants"; + +export interface Interface_MailFields { + emailTo: string; + subject: string; + body: string; +} + +export const mailer = (mailFields: Interface_MailFields) => { + // Nodemailer configuration + const transporter = nodemailer.createTransport({ + service: "gmail", + auth: { + user: process.env.MAIL_USERNAME, + pass: process.env.MAIL_PASSWORD, + }, + }); + + const mailOptions = { + from: "Talawa<>noreply@gmail.com", + to: mailFields.emailTo, + subject: mailFields.subject, + html: mailFields.body, + }; + + return new Promise((resolve, reject) => { + transporter.sendMail(mailOptions, function (error, info) { + if (error) { + reject(ERROR_IN_SENDING_MAIL); + } else { + resolve(info); + } + }); + }); +}; diff --git a/src/lib/utilities/reuploadDuplicateCheck.ts b/src/lib/utilities/reuploadDuplicateCheck.ts new file mode 100644 index 0000000000..5fbb255a4c --- /dev/null +++ b/src/lib/utilities/reuploadDuplicateCheck.ts @@ -0,0 +1,61 @@ +import { imageHash } from "image-hash"; +import { requestContext, errors } from "../libraries"; + +interface UrlRequestObject { + encoding?: string | null; + url: string | null; +} + +interface BufferObject { + ext?: string; + data: Buffer; + name?: string; +} + +export type Type_ImagePath = string | UrlRequestObject | BufferObject; + +const getImageHash = (oldSrc: Type_ImagePath) => { + return new Promise((resolve, reject) => { + imageHash(oldSrc, 16, true, (error: Error, data: any) => { + if (error) { + reject(error); + } + + resolve(data); + }); + }); +}; + +export const reuploadDuplicateCheck = async ( + oldImagePath: Type_ImagePath | null, + newImagePath: Type_ImagePath +) => { + /* + This function checks whether a user is trying to re-upload the same profile picture + or an organization is trying to re-upload the same organization image + */ + try { + if (oldImagePath) { + const oldImageHash = await getImageHash(oldImagePath); + + const newImageHash = await getImageHash(newImagePath); + + return oldImageHash === newImageHash; + } + + return false; + } catch (error) { + console.error(error); + + throw new errors.ValidationError( + [ + { + message: requestContext.translate("invalid.fileType"), + code: "invalid.fileType", + param: "fileType", + }, + ], + requestContext.translate("invalid.fileType") + ); + } +}; diff --git a/src/lib/utilities/uploadImage.ts b/src/lib/utilities/uploadImage.ts new file mode 100644 index 0000000000..6cd2a81fad --- /dev/null +++ b/src/lib/utilities/uploadImage.ts @@ -0,0 +1,55 @@ +import { createWriteStream } from "fs"; +import path from "path"; +import shortid from "shortid"; +import { logger } from "../libraries"; +import { imageAlreadyInDbCheck } from "./imageAlreadyInDbCheck"; +import { deleteImage } from "./deleteImage"; +import { imageExtensionCheck } from "./imageExtensionCheck"; + +export const uploadImage = async ( + newImageFile: any, + oldImagePath: string | null +) => { + const id = shortid.generate(); + + const { createReadStream, filename } = await newImageFile; + + // throw an error if file is not png or jpg + await imageExtensionCheck(filename); + + // upload new image + await new Promise((resolve, reject) => + createReadStream() + .pipe( + createWriteStream( + path.join(__dirname, "../images", `/${id}-${filename}`) + ) + ) + .on("close", resolve) + .on("error", (error: any) => reject(error)) + .on("finish", () => + resolve({ + path, + }) + ) + ); + + const newImagePath = `images/${id}-${filename}`; + + if (oldImagePath) { + logger.info("old image should be deleted"); + + // If user/organization already has an image delete it from the API + await deleteImage(oldImagePath, newImagePath); + } + + const imageAlreadyInDbPath = await imageAlreadyInDbCheck( + oldImagePath, + newImagePath + ); + + return { + newImagePath, + imageAlreadyInDbPath, + }; +}; diff --git a/locales/en.json b/src/locales/en.json similarity index 100% rename from locales/en.json rename to src/locales/en.json diff --git a/locales/fr.json b/src/locales/fr.json similarity index 100% rename from locales/fr.json rename to src/locales/fr.json diff --git a/locales/hi.json b/src/locales/hi.json similarity index 100% rename from locales/hi.json rename to src/locales/hi.json diff --git a/locales/sp.json b/src/locales/sp.json similarity index 100% rename from locales/sp.json rename to src/locales/sp.json diff --git a/locales/zh.json b/src/locales/zh.json similarity index 100% rename from locales/zh.json rename to src/locales/zh.json diff --git a/src/server.ts b/src/server.ts new file mode 100644 index 0000000000..fe88fe6a75 --- /dev/null +++ b/src/server.ts @@ -0,0 +1,180 @@ +import "dotenv/config"; // pull env variables from .env file +import http from "http"; +import path from "path"; +import express from "express"; +import { ApolloServer, PubSub } from "apollo-server-express"; +import depthLimit from "graphql-depth-limit"; +import rateLimit from "express-rate-limit"; +// No type defintions available for package 'xss-clean' +// @ts-ignore +import xss from "xss-clean"; +import helmet from "helmet"; +import mongoSanitize from "express-mongo-sanitize"; +import jwt from "jsonwebtoken"; +import cors from "cors"; +import requestLogger from "morgan"; +import i18n from "i18n"; +import * as database from "./db"; +import { logger, requestContext, requestTracing } from "./lib/libraries"; +import { appConfig } from "./lib/config"; +import { isAuth } from "./lib/middleware"; +import { + AuthenticationDirective, + RoleAuthorizationDirective, +} from "./lib/directives"; +import { typeDefs } from "./lib/typeDefs"; +import { resolvers } from "./lib/resolvers"; +import { Interface_JwtTokenPayload } from "./lib/utilities"; + +const app = express(); + +app.use(requestTracing.middleware()); + +const pubsub = new PubSub(); + +const apiLimiter = rateLimit({ + windowMs: 60 * 60 * 1000, + max: 50000, + message: "Too many requests from this IP, please try again after 15 minutes", +}); + +i18n.configure({ + directory: `${__dirname}/locales`, + staticCatalog: { + en: require("./locales/en.json"), + hi: require("./locales/hi.json"), + zh: require("./locales/zh.json"), + sp: require("./locales/sp.json"), + fr: require("./locales/fr.json"), + }, + queryParameter: "lang", + defaultLocale: appConfig.defaultLocale, + locales: appConfig.supportedLocales, + autoReload: process.env.NODE_ENV !== "production", + updateFiles: process.env.NODE_ENV !== "production", + syncFiles: process.env.NODE_ENV !== "production", +}); + +app.use(i18n.init); +app.use(apiLimiter); +app.use(xss()); +app.use( + helmet({ + contentSecurityPolicy: + process.env.NODE_ENV === "production" ? undefined : false, + }) +); +app.use(mongoSanitize()); +app.use(cors()); + +// Invalid code. Needs fix. +app.use( + requestLogger( + // @ts-ignore + ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms', + { + stream: logger.stream, + } + ) +); +app.use("/images", express.static(path.join(__dirname, "./images"))); +app.use(requestContext.middleware()); + +app.get("/", (req, res) => + res.json({ + "talawa-version": "v1", + status: "healthy", + }) +); + +const httpServer = http.createServer(app); + +const apolloServer = new ApolloServer({ + typeDefs, + resolvers, + validationRules: [depthLimit(5)], + schemaDirectives: { + auth: AuthenticationDirective, + role: RoleAuthorizationDirective, + }, + context: ({ req, res, connection }) => { + if (connection) { + return { + ...connection, + pubsub, + res, + req, + }; + } else { + return { + ...isAuth(req), + pubsub, + res, + req, + }; + } + }, + formatError: (error: any) => { + if (!error.originalError) { + return error; + } + const message = error.message || "Something went wrong !"; + const data = error.originalError.errors || []; + const code = error.originalError.code || 422; + logger.error(message, error); + return { + message, + status: code, + data, + }; + }, + subscriptions: { + onConnect: (connection: any) => { + if (!connection.authorization) { + throw new Error("userAuthentication"); + } + let userId = null; + + const token = connection.authorization.split(" ")[1]; + if (token) { + const decodedToken = jwt.verify( + token, + process.env.ACCESS_TOKEN_SECRET as string + ) as Interface_JwtTokenPayload; + userId = decodedToken.userId; + } + + return { + currentUserToken: connection, + currentUserId: userId, + }; + }, + }, +}); + +apolloServer.applyMiddleware({ + app, +}); +apolloServer.installSubscriptionHandlers(httpServer); + +const serverStart = async () => { + try { + await database.connect(); + httpServer.listen(process.env.PORT || 4000, () => { + logger.info( + `🚀 Server ready at http://localhost:${process.env.PORT || 4000}${ + apolloServer.graphqlPath + }` + ); + logger.info( + `🚀 Subscriptions ready at ws://localhost:${process.env.PORT || 4000}${ + apolloServer.subscriptionsPath + }` + ); + }); + } catch (error) { + logger.error("Error while connecting to database", error); + } +}; + +serverStart(); diff --git a/tests/auth.spec.js b/tests/auth.spec.js deleted file mode 100644 index cd9220dfcf..0000000000 --- a/tests/auth.spec.js +++ /dev/null @@ -1,254 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const shortid = require('shortid'); - -let accessToken; -let refreshToken; -let userId; - -describe('userAuth resolvers', () => { - let email = `${shortid.generate().toLowerCase()}@test.com`; - - test('signUp', async () => { - const response = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"testdb2", - lastName:"testdb2" - email: "${email}" - password:"password" - }) { - user { - _id - firstName - lastName - email - userType - appLanguageCode - image - tokenVersion - } - accessToken - refreshToken - } - } - `, - }); - const { data } = response; - expect(data.data.signUp).toEqual( - expect.objectContaining({ - user: expect.objectContaining({ - _id: expect.any(String), - firstName: 'testdb2', - lastName: 'testdb2', - email: `${email}`, - userType: 'USER', - appLanguageCode: 'en', - image: null, - tokenVersion: 0, - }), - accessToken: expect.any(String), - refreshToken: expect.any(String), - }) - ); - }); - - test('login', async () => { - const response = await axios.post(URL, { - query: ` - mutation { - login(data: { email: "${email}", password: "password" }) { - user { - _id - firstName - lastName - email - userType - image - tokenVersion - } - accessToken - refreshToken - } - } - `, - }); - const { data } = response; - accessToken = data.data.login.accessToken; - refreshToken = data.data.login.refreshToken; - userId = data.data.login.user._id; - expect(data.data.login).toEqual( - expect.objectContaining({ - user: expect.objectContaining({ - _id: expect.any(String), - firstName: 'testdb2', - lastName: 'testdb2', - email: `${email}`, - userType: 'USER', - image: null, - tokenVersion: 0, - }), - accessToken: expect.any(String), - refreshToken: expect.any(String), - }) - ); - }); - - test('refresh Token for User', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - refreshToken( - refreshToken: "${refreshToken}" - ) { - accessToken - refreshToken - } - } - `, - }, - { - headers: { - authorization: `Bearer ${accessToken}`, - }, - } - ); - const { data } = response; - expect(data.data.refreshToken).toEqual( - expect.objectContaining({ - accessToken: expect.any(String), - refreshToken: expect.any(String), - }) - ); - }); - - test('refresh Token (If Invalid)', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - refreshToken( - refreshToken: "${refreshToken + 'as'}" - ) { - accessToken - refreshToken - } - } - `, - }, - { - headers: { - authorization: `Bearer ${accessToken}`, - }, - } - ); - const { data } = response; - expect(data.errors[0]).toEqual( - expect.objectContaining({ - message: 'invalid signature', - status: 422, - data: [], - }) - ); - - expect(data.data).toEqual(null); - }); - - test('revoke refresh Token for user', async () => { - const revokeResponse = await axios.post(URL, { - query: ` - mutation { - revokeRefreshTokenForUser(userId:"${userId}") - } - `, - }); - - const { data } = revokeResponse; - - expect(data.data).toEqual( - expect.objectContaining({ - revokeRefreshTokenForUser: true, - }) - ); - }); - - test('Check Token Version After Revoke refresh Token for user', async () => { - const revokeResponse = await axios.post( - URL, - { - query: ` - query{ - me{ - _id - firstName - lastName - email - tokenVersion - } - } - `, - }, - { - headers: { - authorization: `Bearer ${accessToken}`, - }, - } - ); - - const { data } = revokeResponse; - - expect(data.data.me).toEqual( - expect.objectContaining({ - _id: userId, - firstName: 'testdb2', - lastName: 'testdb2', - email: email, - tokenVersion: 1, - }) - ); - }); - - test('refresh Token for user (After Revoked)', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - refreshToken( - refreshToken: "${refreshToken}" - ) { - accessToken - refreshToken - } - } - `, - }, - { - headers: { - authorization: `Bearer ${accessToken}`, - }, - } - ); - const { data } = response; - expect(data.errors[0]).toEqual( - expect.objectContaining({ - message: 'Invalid refresh token', - status: 422, - }) - ); - - expect(data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: 'Invalid refresh token', - code: 'invalid.refreshToken', - param: 'refreshToken', - }) - ); - - expect(data.data).toEqual(null); - }); -}); diff --git a/tests/chats.spec.js b/tests/chats.spec.js deleted file mode 100644 index 78429b8f55..0000000000 --- a/tests/chats.spec.js +++ /dev/null @@ -1,276 +0,0 @@ -const axios = require('axios'); -const shortid = require('shortid'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const getUserId = require('./functions/getUserId'); - -let token; -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); -}); - -describe('chat resolvers', () => { - let createdGroupChatId; - let createdDirectChatId; - let createdOrgId; - - test('create direct chat', async () => { - // CREATE AN ORGANIZATION - - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - - // CREATE A NEW USER - const nameForNewUser = shortid.generate(); - const email = `${nameForNewUser}@test.com`; - - const createNewUserResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForNewUser}", - lastName:"${nameForNewUser}" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = createNewUserResponse.data; - const newUserId = signUpData.data.signUp.user._id; - - // CREATE DIRECT CHAT - - const createDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - createDirectChat(data: { - organizationId: "${createdOrgId}" - userIds: ["${userId}", "${newUserId}"] - }){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const createDirectChatData = createDirectChatResponse.data; - createdDirectChatId = createDirectChatData.data.createDirectChat._id; - expect(createDirectChatData.data.createDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // SEND A MESSAGE TO A DIRECT CHAT - - test('send message to direct chat', async () => { - const sendMessageToDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMessageToDirectChat(chatId: "${createdDirectChatId}", messageContent: "this is a test message"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const sendMessageToADirectChatData = sendMessageToDirectChatResponse.data; - expect(sendMessageToADirectChatData.data.sendMessageToDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // REMOVE DIRECT CHAT - - test('remove direct chat', async () => { - const removeDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - removeDirectChat(chatId:"${createdDirectChatId}", organizationId:"${createdOrgId}") { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const removeDirectChatData = removeDirectChatResponse.data; - expect(removeDirectChatData.data.removeDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // CREATE GROUP CHAT - - test('create group chat', async () => { - const nameForNewUser = shortid.generate(); - const email = `${nameForNewUser}@test.com`; - const createNewUserResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForNewUser}", - lastName:"${nameForNewUser}" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = createNewUserResponse.data; - const newUserId = signUpData.data.signUp.user._id; - - const createGroupChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - createGroupChat(data: { - title: "This is a group chat for testing" - organizationId: "${createdOrgId}" - userIds: ["${userId}", "${newUserId}"] - }){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const createGroupChatData = createGroupChatResponse.data; - createdGroupChatId = createGroupChatData.data.createGroupChat._id; - - expect(createGroupChatData.data.createGroupChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // SEND MESSAGE TO GROUP CHAT - - test('send message to group chat', async () => { - const sendMessageToGroupChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMessageToGroupChat(chatId: "${createdGroupChatId}", messageContent: "this is a test message"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const sendMessageToAGroupChatData = sendMessageToGroupChatResponse.data; - expect(sendMessageToAGroupChatData.data.sendMessageToGroupChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // REMOVE GROUP CHAT - - test('remove group chat', async () => { - const removeGroupChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - removeGroupChat(chatId:"${createdGroupChatId}") { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const removeGroupChatData = removeGroupChatResponse.data; - expect(removeGroupChatData.data.removeGroupChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); -}); diff --git a/tests/event.spec.js b/tests/event.spec.js deleted file mode 100644 index 83d9345c5b..0000000000 --- a/tests/event.spec.js +++ /dev/null @@ -1,661 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const getUserId = require('./functions/getUserId'); -const shortid = require('shortid'); - -let token; -let userId; -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); -}); -describe('event resolvers', () => { - let createdEventId; - let createdOrgId; - test('createEvent', async () => { - const newOrg = await axios.post( - URL, - { - query: ` - mutation { - createOrganization( - data: { - name: "test org" - description: "test description2" - isPublic: true - visibleInSearch: true - } - ) { - _id - name - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - createdOrgId = newOrg.data.data.createOrganization._id; - - const response = await axios.post( - URL, - { - query: ` - mutation { - createEvent( - data: { - title: "Talawa Conference Test" - description: "National conference that happens yearly" - isPublic: true - isRegisterable: true - recurring: true - recurrance: YEARLY - location: "Test" - startDate: "2/2/2020" - allDay: true - endTime: "2:00 PM" - startTime: "1:00 PM" - organizationId: "${createdOrgId}" - } - ) { - _id - title - description - startDate - startTime - endTime - allDay - recurring - recurrance - isPublic - isRegisterable - location - status - organization { - _id - } - creator { - _id - } - admins { - _id - } - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - createdEventId = data.data.createEvent._id; - const createdEvent = data.data.createEvent; - expect(createdEvent).toEqual( - expect.objectContaining({ - _id: expect.any(String), - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - startDate: '2/2/2020', - startTime: '1:00 PM', - endTime: '2:00 PM', - allDay: true, - recurring: true, - recurrance: 'YEARLY', - isPublic: true, - isRegisterable: true, - location: 'Test', - status: 'ACTIVE', - }) - ); - - expect(createdEvent.organization).toEqual( - expect.objectContaining({ - _id: createdOrgId, - }) - ); - - expect(createdEvent.creator).toEqual( - expect.objectContaining({ - _id: userId, - }) - ); - - createdEvent.admins.map((admin) => { - expect(admin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - }); - - test('allEvents', async () => { - const response = await axios.post(URL, { - query: `{ - events { - _id - title - description - startDate - startTime - endTime - allDay - recurring - recurring - recurrance - isPublic - isRegisterable - location - status - registrants{ - _id - user{ - _id - } - } - } - }`, - }); - const { data } = response; - const eventsData = data.data.events; - expect(Array.isArray(eventsData)).toBeTruthy(); - - eventsData.map((event) => { - expect(event).toEqual( - expect.objectContaining({ - _id: expect.any(String), - title: expect.any(String), - description: expect.any(String), - startDate: expect.any(String), - startTime: expect.any(String), - endTime: expect.any(String), - allDay: expect.any(Boolean), - recurring: expect.any(Boolean), - recurrance: expect.any(String), - isPublic: expect.any(Boolean), - isRegisterable: expect.any(Boolean), - location: expect.any(String), - status: expect.any(String), - }) - ); - event.registrants.map((registrant) => { - expect(registrant).toEqual( - expect.objectContaining({ - _id: expect.any(String), - user: expect.objectContaining({ - _id: expect.any(String), - }), - }) - ); - }); - }); - }); - - test('eventsByOrganization', async () => { - const response = await axios.post(URL, { - query: `query { - eventsByOrganization (id: "${createdOrgId}") { - _id - title - } - }`, - }); - const { data } = response; - expect(Array.isArray(data.data.eventsByOrganization)).toBeTruthy(); - expect(data.data.eventsByOrganization).toHaveLength(1); - }); - - test('eventByID', async () => { - const response = await axios.post( - URL, - { - query: ` - query { - event (id: "${createdEventId}"){ - _id - title - description - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data.data.event).toEqual( - expect.objectContaining({ - _id: expect.any(String), - title: expect.any(String), - description: expect.any(String), - }) - ); - }); - - test('check if user is Registered for event', async () => { - const response = await axios.post( - URL, - { - query: `{ - isUserRegister(eventId: "${createdEventId}") { - event { - _id - } - isRegistered - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - const isUserRegistered = data.data.isUserRegister; - expect(isUserRegistered.event).toEqual( - expect.objectContaining({ - _id: createdEventId, - }) - ); - expect(isUserRegistered.isRegistered).toEqual(true); - }); - - test('check all registered events by user', async () => { - const response = await axios.post( - URL, - { - query: `{ - registeredEventsByUser(id: "${userId}") { - _id - title - description - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - const registeredEventsByUserData = data.data.registeredEventsByUser; - expect(Array.isArray(registeredEventsByUserData)).toBeTruthy(); - - registeredEventsByUserData.map((event) => { - expect(event).toEqual( - expect.objectContaining({ - _id: expect.any(String), - title: expect.any(String), - description: expect.any(String), - }) - ); - }); - }); - - test('registerForEvent if already registered', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - registerForEvent(id: "${createdEventId}") { - _id - title - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(Array.isArray(data.errors)).toBeTruthy(); - - expect(data.errors[0]).toEqual( - expect.objectContaining({ - message: 'Already registered for the event', - status: 422, - }) - ); - - expect(data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: 'Already registered for the event', - code: 'registrant.alreadyExist', - param: 'registrant', - metadata: {}, - }) - ); - - expect(data.data).toEqual(null); - }); - - test('unregisterForEventByUser', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation{ - unregisterForEventByUser(id:"${createdEventId}"){ - _id - title - description - registrants{ - _id - } - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - - expect(data.data.unregisterForEventByUser).toEqual( - expect.objectContaining({ - _id: createdEventId, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - }) - ); - }); - - test('registerForEvent after unregistering', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - registerForEvent(id: "${createdEventId}") { - _id - title - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - - expect(data.data.registerForEvent).toEqual( - expect.objectContaining({ - _id: createdEventId, - title: 'Talawa Conference Test', - }) - ); - }); - - test('registrantsByEvent', async () => { - const response = await axios.post(URL, { - query: `query { - registrantsByEvent (id: "${createdEventId}") { - firstName - email - } - }`, - }); - const { data } = response; - expect(Array.isArray(data.data.registrantsByEvent)).toBeTruthy(); - }); - - test('updateEvent', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - updateEvent(id: "${createdEventId}", data: { - title: "Talawa Congress" - }) { - _id - title - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data).toMatchObject({ - data: { - updateEvent: { - _id: `${createdEventId}`, - title: 'Talawa Congress', - }, - }, - }); - }); - - // Event Task - - let createdTaskId; - test('createTask', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - createTask( - data: { - title: "Task", - }, eventId: "${createdEventId}") { - _id - title - description - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - createdTaskId = data.data.createTask._id; - expect(data).toMatchObject({ - data: { - createTask: { - _id: `${createdTaskId}`, - title: 'Task', - }, - }, - }); - }); - - test('updateTask', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - updateTask(id: "${createdTaskId}", data: { - title: "Updated" - }) { - _id - title - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data).toMatchObject({ - data: { - updateTask: { - _id: `${createdTaskId}`, - title: 'Updated', - }, - }, - }); - }); - - test('tasksByEvent', async () => { - const response = await axios.post(URL, { - query: `query { - tasksByEvent (id: "${createdEventId}") { - title - description - } - }`, - }); - const { data } = response; - expect(Array.isArray(data.data.tasksByEvent)).toBeTruthy(); - }); - - test('removeTask', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - createTask( - data: { - title: "TaskRemove", - }, eventId: "${createdEventId}") { - _id - title - description - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = response; - - const newTaskId = data.data.createTask._id; - - const deletedResponse = await axios.post( - URL, - { - query: ` - mutation { - removeTask(id: "${newTaskId}") { - _id - title - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(deletedResponse.data).toMatchObject({ - data: { - removeTask: { - _id: `${newTaskId}`, - title: 'TaskRemove', - }, - }, - }); - }); - - test('removeEvent', async () => { - // a new organization is created then deleted - const response = await axios.post( - URL, - { - query: ` - mutation { - createEvent( - data: { - title: "Talawa Conference Test" - description: "National conference that happens yearly" - isPublic: true - isRegisterable: true - recurring: true - recurrance: YEARLY - location: "Test" - startDate: "2/2/2020" - allDay: true - endTime: "2:00 PM" - startTime: "1:00 PM" - organizationId: "${createdOrgId}" - } - ) { - _id - title - description - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const newEventId = response.data.data.createEvent._id; - - const deletedResponse = await axios.post( - URL, - { - query: ` - mutation { - removeEvent(id: "${newEventId}") { - _id - title - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(deletedResponse.data).toMatchObject({ - data: { - removeEvent: { - _id: `${newEventId}`, - title: 'Talawa Conference Test', - }, - }, - }); - }); -}); diff --git a/tests/functions/getToken.js b/tests/functions/getToken.js deleted file mode 100644 index 404fc2fac3..0000000000 --- a/tests/functions/getToken.js +++ /dev/null @@ -1,54 +0,0 @@ -const axios = require('axios'); - -const { URL } = require('../../constants'); - -// sets token before every test -module.exports = async (email) => { - const response = await axios.post(URL, { - query: ` - mutation{ - login(data:{ - email:"${email}", - password:"password" - }){ - user{ - _id - } - accessToken - refreshToken - } - } - `, - }); - - const { data } = response; - if (data.data !== null) { - return data.data.login.accessToken; - } else { - const signUpResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"testdb2", - lastName:"testdb2" - email: "${email}" - password:"password" - }) { - user { - _id - firstName - lastName - email - userType - appLanguageCode - image - } - accessToken - } - } - `, - }); - const { data } = signUpResponse; - return data.data.signUp.accessToken; - } -}; diff --git a/tests/functions/getUserId.js b/tests/functions/getUserId.js deleted file mode 100644 index bcc87ca687..0000000000 --- a/tests/functions/getUserId.js +++ /dev/null @@ -1,25 +0,0 @@ -const axios = require('axios'); - -const { URL } = require('../../constants'); - -module.exports = async (email) => { - const response = await axios.post(URL, { - query: ` - mutation{ - login(data:{ - email:"${email}", - password:"password" - }){ - user{ - _id - } - accessToken - refreshToken - } - } - `, - }); - - const { data } = response; - return data.data.login.user._id; -}; diff --git a/tests/functions/getUserIdFromSignup.js b/tests/functions/getUserIdFromSignup.js deleted file mode 100644 index 5350ff669a..0000000000 --- a/tests/functions/getUserIdFromSignup.js +++ /dev/null @@ -1,28 +0,0 @@ -const axios = require('axios'); - -const { URL } = require('../../constants'); - -module.exports = async (email) => { - const response = await axios.post(URL, { - query: ` - mutation{ - signUp(data:{ - email:"${email}", - password:"password", - firstName:"firstName", - lastName:"lastName", - appLanguageCode:"en" - }){ - user{ - _id - } - accessToken - refreshToken - } - } - `, - }); - - const { data } = response; - return data.data.signUp.user._id; -}; diff --git a/tests/functions/superAdminCheck.spec.js b/tests/functions/superAdminCheck.spec.js deleted file mode 100644 index 9d621f305d..0000000000 --- a/tests/functions/superAdminCheck.spec.js +++ /dev/null @@ -1,30 +0,0 @@ -const shortid = require('shortid'); -const getUserId = require('./getUserIdFromSignup'); -const superAdminCheck = require('../../lib/resolvers/functions/superAdminCheck'); - -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); -}); - -describe('Testing is the user is Super Admin', () => { - test('should not throw an error if current user is of type : SUPERADMIN', () => { - expect(() => { - superAdminCheck({ userId: userId }, { userType: 'SUPERADMIN' }); - }).not.toThrow('User is not authorized for performing this operation'); - }); - - test('should throw an error if current user is of type : USER', () => { - expect(() => { - superAdminCheck({ userId: userId }, { userType: 'USER' }); - }).toThrow('User is not authorized for performing this operation'); - }); - - test('should throw an error if current user is of type : ADMIN', () => { - expect(() => { - superAdminCheck({ userId: userId }, { userType: 'ADMIN' }); - }).toThrow('User is not authorized for performing this operation'); - }); -}); diff --git a/tests/language.spec.js b/tests/language.spec.js deleted file mode 100644 index e3ff77aabb..0000000000 --- a/tests/language.spec.js +++ /dev/null @@ -1,40 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const shortid = require('shortid'); - -let token; -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('language resolvers', () => { - test('updateLanguage', async () => { - const langaugeCodes = ['en', 'es', 'fr', 'hi', 'zh', 'de', 'ja', 'pt']; - - const languageCode = - langaugeCodes[Math.floor(Math.random() * langaugeCodes.length)]; - - const response = await axios.post( - URL, - { - query: ` - mutation { - updateLanguage(languageCode: "${languageCode}") { - _id - appLanguageCode - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data.data.updateLanguage.appLanguageCode).toBe(languageCode); - }); -}); diff --git a/tests/newsfeed.spec.js b/tests/newsfeed.spec.js deleted file mode 100644 index c622a80e92..0000000000 --- a/tests/newsfeed.spec.js +++ /dev/null @@ -1,436 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const mongoose = require('mongoose'); -const shortid = require('shortid'); - -let token; -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('newsfeed resolvers', () => { - test('posts', async () => { - const response = await axios.post(URL, { - query: `query { - posts { - _id - text - creator { - firstName - email - } - comments { - text - creator { - firstName - } - } - likedBy { - firstName - } - } - }`, - }); - const { data } = response; - expect(Array.isArray(data.data.posts)).toBeTruthy(); - }); - - let createdPostId; - let createdOrgId; - test('Create Post', async () => { - const newOrg = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - name - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - createdOrgId = newOrg.data.data.createOrganization._id; - - const response = await axios.post( - URL, - { - query: ` - mutation { - createPost( - data: { - text: "Test Post", - organizationId: "${createdOrgId}", - }) { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - createdPostId = data.data.createPost._id; - expect(data.data.createPost).toEqual( - expect.objectContaining({ - _id: expect.any(String), - text: expect.any(String), - }) - ); - }); - - test('Create Post without existing Organization', async () => { - const dummyOrgId = new mongoose.Types.ObjectId(); - const response = await axios.post( - URL, - { - query: ` - mutation { - createPost( - data: { - text: "Test Post", - organizationId: "${dummyOrgId}", - }) { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(response.data.errors[0]).toEqual( - expect.objectContaining({ - message: 'Organization not found', - status: 422, - }) - ); - - expect(response.data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: 'Organization not found', - code: 'organization.notFound', - param: 'organization', - metadata: {}, - }) - ); - - expect(response.data.data.createPost).toEqual(null); - }); - - test('Posts by Organization', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${createdOrgId}") { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const { data } = response; - expect(Array.isArray(data.data.postsByOrganization)).toBeTruthy(); - }); - - test('Remove Post', async () => { - // a new organization is created then deleted - const response = await axios.post( - URL, - { - query: ` - mutation { - createPost( - data: { - text: "Test", - organizationId: "${createdOrgId}", - }) { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const newPostId = response.data.data.createPost._id; - - const deletedResponse = await axios.post( - URL, - { - query: ` - mutation { - removePost(id: "${newPostId}") { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(deletedResponse.data).toMatchObject({ - data: { - removePost: { - _id: `${newPostId}`, - text: 'Test', - }, - }, - }); - }); - - test('Like Post', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - likePost( - id: "${createdPostId}" - ) { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data.data.likePost).toEqual( - expect.objectContaining({ - _id: expect.any(String), - text: expect.any(String), - }) - ); - }); - - test('Unlike Post', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - unlikePost( - id: "${createdPostId}" - ) { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data.data.unlikePost).toEqual( - expect.objectContaining({ - _id: expect.any(String), - text: expect.any(String), - }) - ); - }); - - // Comments - - let createdCommentId; - test('Create Comment', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - createComment( - postId: "${createdPostId}", - data: { - text: "This is my first comment!", - }) { - _id - text - } - } - - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - createdCommentId = data.data.createComment._id; - expect(data.data.createComment).toEqual( - expect.objectContaining({ - _id: expect.any(String), - text: expect.any(String), - }) - ); - }); - - test('Like Comment', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - likeComment( - id: "${createdCommentId}" - ) { - _id - text - likeCount - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data.data.likeComment).toEqual( - expect.objectContaining({ - _id: expect.any(String), - text: expect.any(String), - likeCount: expect.any(Number), - }) - ); - }); - - test('Unlike Comment', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - unlikeComment( - id: "${createdCommentId}" - ) { - _id - text - likeCount - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(data.data.unlikeComment).toEqual( - expect.objectContaining({ - _id: expect.any(String), - text: expect.any(String), - likeCount: expect.any(Number), - }) - ); - }); - - test('Remove Comment', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - createComment( - postId: "${createdPostId}", - data: { - text: "Comment to be deleted", - }) { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const newCommentId = response.data.data.createComment._id; - - const deletedResponse = await axios.post( - URL, - { - query: ` - mutation { - removeComment(id: "${newCommentId}") { - _id - text - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(deletedResponse.data).toMatchObject({ - data: { - removeComment: { - _id: `${newCommentId}`, - text: 'Comment to be deleted', - }, - }, - }); - }); -}); diff --git a/tests/organization.spec.js b/tests/organization.spec.js deleted file mode 100644 index b7786ed27d..0000000000 --- a/tests/organization.spec.js +++ /dev/null @@ -1,303 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const shortid = require('shortid'); - -let token; -let createdOrgId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('organization resolvers', () => { - test('allOrganizations', async () => { - const response = await axios.post(URL, { - query: `{ - organizations { - _id - name - } - } - `, - }); - const { data } = response; - expect(Array.isArray(data.data.organizations)).toBeTruthy(); - }); - - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - test('createOrganization', async () => { - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - apiUrl : "test url" - }) { - _id, - name, - description, - creator{ - email - }, - admins{ - email - }, - members{ - email - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = createdOrgResponse; - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - expect(data.data.createOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - description: expect.any(String), - creator: expect.objectContaining({ - email: expect.any(String), - }), - admins: expect.any(Array), - members: expect.any(Array), - }) - ); - // test to check if userInfo has been updated - const userInfoResponse = await axios.post( - URL, - { - query: ` - query { - me { - joinedOrganizations{ - _id - }, - createdOrganizations{ - _id - }, - adminFor{ - _id - }, - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const userData = userInfoResponse.data.data.me; - expect(userData).toEqual( - expect.objectContaining({ - joinedOrganizations: expect.arrayContaining([ - expect.objectContaining({ - _id: createdOrgId, - }), - ]), - createdOrganizations: expect.arrayContaining([ - expect.objectContaining({ - _id: createdOrgId, - }), - ]), - adminFor: expect.arrayContaining([ - expect.objectContaining({ - _id: createdOrgId, - }), - ]), - }) - ); - }); - - test('updateOrganization', async () => { - const updateOrgRes = await axios.post( - URL, - { - query: ` - mutation { - updateOrganization( - id: "${createdOrgId}" - data: { - name: "test2 org" - description: "new description" - isPublic: ${!isPublic_boolean} - visibleInSearch: ${!visibleInSearch_boolean} - } - ) { - _id - name - description - isPublic - visibleInSearch - apiUrl - image - creator { - _id - firstName - } - members { - _id - firstName - } - admins { - _id - firstName - } - membershipRequests { - _id - organization{ - _id - name - description - } - user { - _id - firstName - } - } - blockedUsers { - _id - firstName - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = updateOrgRes; - const updatedOrganizationData = data.data.updateOrganization; - expect(updatedOrganizationData).toEqual( - expect.objectContaining({ - _id: createdOrgId, - name: 'test2 org', - description: 'new description', - isPublic: !isPublic_boolean, - visibleInSearch: !visibleInSearch_boolean, - apiUrl: 'test url', - image: null, - creator: expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }), - }) - ); - - updatedOrganizationData.members.map((member) => { - expect(member).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - updatedOrganizationData.admins.map((admin) => { - expect(admin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - updatedOrganizationData.membershipRequests.map((membershipRequest) => { - expect(membershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - organization: expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - description: expect.any(String), - }), - user: expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }), - }) - ); - }); - - updatedOrganizationData.blockedUsers.map((blockedUser) => { - expect(blockedUser).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - }); - - test('removeOrganization', async () => { - const deletedResponse = await axios.post( - URL, - { - query: ` - mutation { - removeOrganization(id: "${createdOrgId}") { - _id, - email - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const userInfoResponse = await axios.post( - URL, - { - query: ` - query { - me { - _id, - email - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const userDataFromQuery = userInfoResponse.data.data.me; - const userData = deletedResponse.data.data.removeOrganization; - - expect(userData).toEqual( - expect.objectContaining({ - _id: expect.any(String), - email: expect.any(String), - }) - ); - - // check if both objects are same with values. - expect(userDataFromQuery).toMatchObject(userData); - }); -}); diff --git a/tests/organization_subqueries.spec.js b/tests/organization_subqueries.spec.js deleted file mode 100644 index 202fbad989..0000000000 --- a/tests/organization_subqueries.spec.js +++ /dev/null @@ -1,108 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); - -describe('organization resolvers', () => { - test('organization-subqueries', async () => { - const response = await axios.post(URL, { - query: ` - { - organizations { - _id - name - description - isPublic - creator { - _id - firstName - } - members { - _id - firstName - } - admins { - _id - firstName - } - membershipRequests { - _id - user { - _id - firstName - } - organization { - _id - name - description - } - } - blockedUsers { - _id - } - } - } - `, - }); - - const { data } = response; - - expect(Array.isArray(data.data.organizations)).toBeTruthy(); - - data.data?.organizations.map((org) => { - expect(org).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - creator: expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }), - }) - ); - - org.members.map((member) => { - expect(member).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - org.admins.map((admin) => { - expect(admin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - org.membershipRequests.map((membershipRequest) => { - expect(membershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - user: expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }), - organization: expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - description: expect.any(String), - }), - }) - ); - }); - - org.blockedUsers.map((blockedUser) => { - expect(blockedUser).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - }); - }); -}); diff --git a/tests/organizations_connection.spec.js b/tests/organizations_connection.spec.js deleted file mode 100644 index 1444b57d75..0000000000 --- a/tests/organizations_connection.spec.js +++ /dev/null @@ -1,264 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const shortid = require('shortid'); - -let token; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('Organizations Connection Resolvers', () => { - let createdOrgId; - - test('createOrganization', async () => { - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = createdOrgResponse; - createdOrgId = data?.data.createOrganization._id; - expect(data.data.createOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - test('Organizations Connection with Filter id', async () => { - const orgConnectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsConnection(where: { id:"${createdOrgId}" }) { - _id - name - description - isPublic - visibleInSearch - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect( - orgConnectionResponse.data.data.organizationsConnection - ).toHaveLength(1); - - expect(orgConnectionResponse.data.data.organizationsConnection[0]).toEqual( - expect.objectContaining({ - _id: createdOrgId, - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - }) - ); - }); - - test('Organizations Connection with Filter id_not', async () => { - const orgConnectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsConnection(where:{id_not:"${createdOrgId}"}) { - _id - name - description - isPublic - visibleInSearch - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - orgConnectionResponse.data?.data.organizationsConnection.forEach((org) => { - expect(org).not.toEqual( - expect.objectContaining({ - _id: createdOrgId, - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - }) - ); - }); - }); - - test('Organizations Connection with Filter id_in', async () => { - const orgConnectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsConnection(where:{id_in:"${createdOrgId}"}) { - _id - name - description - isPublic - visibleInSearch - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - orgConnectionResponse.data?.data.organizationsConnection.forEach((org) => { - expect(org).toEqual( - expect.objectContaining({ - _id: createdOrgId, - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - }) - ); - }); - }); - - test('Organizations Connection with Filter id_not_in', async () => { - const orgConnectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsConnection(where:{id_not_in:"${createdOrgId}"}) { - _id - name - description - isPublic - visibleInSearch - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - orgConnectionResponse.data?.data.organizationsConnection.forEach((org) => { - expect(org).not.toEqual( - expect.objectContaining({ - _id: createdOrgId, - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - }) - ); - }); - }); - - test('Organizations Connection with Filters - isPublic, visibleInSearch', async () => { - const orgConnectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsConnection(where: { isPublic: true, visibleInSearch: true }) { - _id - name - description - isPublic - visibleInSearch - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - orgConnectionResponse.data.data.organizationsConnection.forEach((org) => { - expect(org).toEqual( - expect.objectContaining({ - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - }) - ); - }); - }); - - test('Organizations Connection with Parameter first=1', async () => { - const orgConnectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsConnection(first:1) { - name - description - isPublic - visibleInSearch - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect( - orgConnectionResponse.data.data.organizationsConnection - ).toHaveLength(1); - - expect(orgConnectionResponse.data.data.organizationsConnection[0]).toEqual( - expect.objectContaining({ - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - }) - ); - }); -}); diff --git a/tests/organizations_member_connection.spec.js b/tests/organizations_member_connection.spec.js deleted file mode 100644 index 2a38cd7f79..0000000000 --- a/tests/organizations_member_connection.spec.js +++ /dev/null @@ -1,269 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const shortid = require('shortid'); - -let token; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('organization member connection resolvers', () => { - let createdOrgId; - - test('createOrganization', async () => { - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = createdOrgResponse; - createdOrgId = data?.data.createOrganization._id; - expect(data.data.createOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - test('Organization Member Connection', async () => { - const orgMemberConnectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsMemberConnection(orgId: "${createdOrgId}") { - pageInfo { - hasNextPage - hasPreviousPage - totalPages - nextPageNo - prevPageNo - currPageNo - } - edges{ - _id - } - aggregate { - count - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - // Method to assert the value with null or a type. - expect.extend({ - toBeTypeOrNull(received, classTypeOrNull) { - try { - expect(received).toEqual(expect.any(classTypeOrNull)); - return { - message: 'Ok', - pass: true, - }; - } catch (error) { - if (received === null) - return { - message: 'Ok', - pass: true, - }; - else - return { - message: `expected ${received} to be ${classTypeOrNull} type or null`, - pass: false, - }; - } - }, - }); - - expect( - orgMemberConnectionResponse.data.data.organizationsMemberConnection - .pageInfo - ).toEqual( - expect.objectContaining({ - hasNextPage: expect.any(Boolean), - hasPreviousPage: expect.any(Boolean), - totalPages: expect.any(Number), - nextPageNo: expect.toBeTypeOrNull(Number), // It may be null or a number - prevPageNo: expect.toBeTypeOrNull(Number), // It may be null or a number - currPageNo: expect.any(Number), - }) - ); - - expect( - orgMemberConnectionResponse.data.data.organizationsMemberConnection.edges - ).toEqual(expect.any(Array)); - - expect( - orgMemberConnectionResponse.data.data.organizationsMemberConnection - .aggregate - ).toEqual( - expect.objectContaining({ - count: expect.any(Number), - }) - ); - }); - - test('Organization Member Connection Without Skip Parameter', async () => { - const connectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsMemberConnection(orgId: "${createdOrgId}", first:1) { - pageInfo { - hasNextPage - hasPreviousPage - totalPages - nextPageNo - prevPageNo - currPageNo - } - edges{ - _id - } - aggregate { - count - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(connectionResponse.data.errors[0]).toEqual( - expect.objectContaining({ - message: 'Skip parameter is missing', - status: 422, - data: [], - }) - ); - - expect(connectionResponse.data.data).toEqual(null); - }); - - test('Organization Member Connection With Skip Parameter as Null', async () => { - const connectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsMemberConnection(orgId: "${createdOrgId}", first:1, skip:null) { - pageInfo { - hasNextPage - hasPreviousPage - totalPages - nextPageNo - prevPageNo - currPageNo - } - edges{ - _id - } - aggregate { - count - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(connectionResponse.data.errors[0]).toEqual( - expect.objectContaining({ - message: - 'Unexpected error value: "Missing Skip parameter. Set it to either 0 or some other value"', - status: 422, - data: [], - }) - ); - - expect(connectionResponse.data.data).toEqual(null); - }); - - test('Organization Member Connection Without Authorization', async () => { - const connectionResponse = await axios.post( - URL, - { - query: ` - query { - organizationsMemberConnection(orgId: "${createdOrgId}") { - pageInfo { - hasNextPage - hasPreviousPage - totalPages - nextPageNo - prevPageNo - currPageNo - } - edges{ - _id - } - aggregate { - count - } - } - } - `, - }, - { - headers: { - Authorization: 'Bearer ', //Empty Token - }, - } - ); - - expect(connectionResponse.data.errors[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - status: 422, - }) - ); - - expect(connectionResponse.data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - code: 'user.notAuthenticated', - param: 'userAuthentication', - metadata: {}, - }) - ); - - expect(connectionResponse.data.data).toEqual(null); - }); -}); diff --git a/tests/private_organization_membership.spec.js b/tests/private_organization_membership.spec.js deleted file mode 100644 index 7dd1e9e472..0000000000 --- a/tests/private_organization_membership.spec.js +++ /dev/null @@ -1,228 +0,0 @@ -const axios = require('axios'); -const shortid = require('shortid'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); - -let token; -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('Private Organization Membership Tests', () => { - let newRequestId; - let createdOrganizationId; - let newUserToken; - - // New user sends membership request to join organization - test('User sends private organization membership request', async () => { - // Private Organization is created - by default user - const createdOrganizationResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: false - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - createdOrganizationId = - createdOrganizationResponse.data.data.createOrganization._id; - - // New user is created - - const id = shortid.generate(); - const email = `${id}@test.com`; - const response = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"testdb2", - lastName:"testdb2" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = response.data; - newUserToken = signUpData.data.signUp.accessToken; - - const sendRequestResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMembershipRequest(organizationId: "${createdOrganizationId}"){ - _id - } - }`, - }, - { - headers: { - Authorization: `Bearer ${newUserToken}`, - }, - } - ); - - const sendRequestData = sendRequestResponse.data; - newRequestId = sendRequestData.data.sendMembershipRequest._id; - - expect(sendRequestData.data.sendMembershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // admin rejects membership request - test('Admin rejects membership request', async () => { - const rejectRequestResponse = await axios.post( - URL, - { - query: ` - mutation{ - rejectMembershipRequest(membershipRequestId: "${newRequestId}"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const rejectRequestData = rejectRequestResponse.data; - - expect(rejectRequestData.data.rejectMembershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // USER SENDS REQUEST THEN CANCELS IT - test('User sends membership requests then cancels it', async () => { - let requestId; - const sendRequestResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMembershipRequest(organizationId: "${createdOrganizationId}"){ - _id - } - }`, - }, - { - headers: { - Authorization: `Bearer ${newUserToken}`, - }, - } - ); - const sendRequestData = sendRequestResponse.data; - requestId = sendRequestData.data.sendMembershipRequest._id; - - const cancelRequestResponse = await axios.post( - URL, - { - query: ` - mutation{ - cancelMembershipRequest(membershipRequestId: "${requestId}"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${newUserToken}`, - }, - } - ); - - const cancelRequestData = cancelRequestResponse.data; - - expect(cancelRequestData.data.cancelMembershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // A NEW REQUEST IS SENT AND ACCEPTED - - test('User sends membership request and admin accepts it', async () => { - // SEND REQUEST - - let requestId; - const sendRequestResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMembershipRequest(organizationId: "${createdOrganizationId}"){ - _id - } - }`, - }, - { - headers: { - Authorization: `Bearer ${newUserToken}`, - }, - } - ); - const sendRequestData = sendRequestResponse.data; - requestId = sendRequestData.data.sendMembershipRequest._id; - - // ACCEPT REQUEST - - const acceptRequestResponse = await axios.post( - URL, - { - query: ` - mutation{ - acceptMembershipRequest(membershipRequestId: "${requestId}"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const acceptRequestData = acceptRequestResponse.data; - - expect(acceptRequestData.data.acceptMembershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); -}); diff --git a/tests/resolver_tests/auth_mutations/login.spec.js b/tests/resolver_tests/auth_mutations/login.spec.js deleted file mode 100644 index 6e50aac845..0000000000 --- a/tests/resolver_tests/auth_mutations/login.spec.js +++ /dev/null @@ -1,54 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const login = require('../../../lib/resolvers/auth_mutations/login'); -const database = require('../../../db'); -const shortid = require('shortid'); - -require('../../../lib/models/Event'); -require('../../../lib/models/MembershipRequest'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Login Mutation', async () => { - // SignUp the User - const nameForNewUser = shortid.generate().toLowerCase(); - const email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - await signup({}, args); - - //Login User - args = { - data: { - email: email, - password: 'password', - }, - }; - const response = await login({}, args); - - expect(response).toEqual( - expect.objectContaining({ - accessToken: expect.any(String), - refreshToken: expect.any(String), - user: expect.objectContaining({ - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - }), - }) - ); - }); -}); diff --git a/tests/resolver_tests/auth_mutations/refresh_token.spec.js b/tests/resolver_tests/auth_mutations/refresh_token.spec.js deleted file mode 100644 index 64c4f76f74..0000000000 --- a/tests/resolver_tests/auth_mutations/refresh_token.spec.js +++ /dev/null @@ -1,41 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const refreshToken = require('../../../lib/resolvers/auth_mutations/refresh_token'); -const database = require('../../../db'); -const shortid = require('shortid'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Refresh Token', async () => { - const nameForNewUser = shortid.generate().toLowerCase(); - const email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signupResponse = await signup({}, args); - const token = signupResponse.refreshToken; - - args = { - refreshToken: token, - }; - const response = await refreshToken({}, args); - expect(response).toEqual( - expect.objectContaining({ - accessToken: expect.any(String), - refreshToken: expect.any(String), - }) - ); - }); -}); diff --git a/tests/resolver_tests/auth_mutations/revoke_refresh_token_for_user.spec.js b/tests/resolver_tests/auth_mutations/revoke_refresh_token_for_user.spec.js deleted file mode 100644 index 012988ec71..0000000000 --- a/tests/resolver_tests/auth_mutations/revoke_refresh_token_for_user.spec.js +++ /dev/null @@ -1,37 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const revokeRefreshTokenForUser = require('../../../lib/resolvers/auth_mutations/revoke_refresh_token_for_user'); -const database = require('../../../db'); -const shortid = require('shortid'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - const nameForNewUser = shortid.generate().toLowerCase(); - const email = `${nameForNewUser}@test.com`; - let userId; - test('Revoke Refresh Token', async () => { - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signupResponse = await signup({}, args); - userId = signupResponse.user._id; - args = { - userId: userId, - }; - - const response = await revokeRefreshTokenForUser({}, args); - expect(response).toEqual(true); - }); -}); diff --git a/tests/resolver_tests/auth_mutations/signup.spec.js b/tests/resolver_tests/auth_mutations/signup.spec.js deleted file mode 100644 index cb0456c7aa..0000000000 --- a/tests/resolver_tests/auth_mutations/signup.spec.js +++ /dev/null @@ -1,40 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const database = require('../../../db'); -const shortid = require('shortid'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Signup Mutation', async () => { - const nameForNewUser = shortid.generate().toLowerCase(); - const email = `${nameForNewUser}@test.com`; - const args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const response = await signup({}, args); - - expect(response).toEqual( - expect.objectContaining({ - accessToken: expect.any(String), - refreshToken: expect.any(String), - user: expect.objectContaining({ - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - }), - }) - ); - }); -}); diff --git a/tests/resolver_tests/event_query/event.spec.js b/tests/resolver_tests/event_query/event.spec.js deleted file mode 100644 index 4bbeab20f2..0000000000 --- a/tests/resolver_tests/event_query/event.spec.js +++ /dev/null @@ -1,193 +0,0 @@ -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganisation = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const removeOrganisation = require('../../../lib/resolvers/organization_mutations/removeOrganization'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const getEvent = require('../../../lib/resolvers/event_query/event'); -const removeEvent = require('../../../lib/resolvers/event_mutations/removeEvent'); -require('../../../lib/models/Task'); -const shortid = require('shortid'); -const axios = require('axios'); -const { URL } = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - let context; - let organizationId; - let eventId; - let userId; - const name = shortid.generate().toLowerCase(); - const startDateOfEvent = new Date().toLocaleDateString(); - - beforeAll(async () => { - // signup and login to create an event - const email = `${name}@test.com`; - const signupArgs = { - data: { - firstName: name, - lastName: name, - email: email, - password: 'password', - }, - }; - const response = await signup({}, signupArgs); - // this userId will be used to create a new event - userId = response.user._id; - context = { - userId: String(userId), - }; - // create an org - const orgName = shortid.generate().toLowerCase(); - const createOrganisationArgs = { - data: { - name: orgName, - description: orgName, - isPublic: true, - visibleInSearch: true, - }, - }; - const createdOrganisation = await createOrganisation( - {}, - createOrganisationArgs, - context - ); - organizationId = createdOrganisation._id; - // create an event - const createEventArgs = { - data: { - title: name, - description: name, - startDate: startDateOfEvent, - startTime: '10:00 AM', - endTime: '3:00 PM', - endDate: startDateOfEvent, - allDay: false, - recurring: false, - isPublic: true, - isRegisterable: true, - organizationId, - tasks: [], - }, - }; - const createdEvent = await createEvent({}, createEventArgs, context); - eventId = createdEvent._id; - }); - - // finally delete that event ,org and user regardless of test passing or failing. - afterAll(async () => { - const removeOrganisationArgs = { - id: organizationId, - }; - await removeOrganisation({}, removeOrganisationArgs, context); - }); - - test('should return the created event', async () => { - // query that event - const getEventArgs = { - id: eventId, - }; - const event = await getEvent({}, getEventArgs); - - // check the event now. - expect(event).toEqual( - expect.objectContaining({ - _id: eventId, - title: name, - description: name, - startDate: startDateOfEvent, - startTime: '10:00 AM', - endTime: '3:00 PM', - endDate: startDateOfEvent, - creator: expect.objectContaining({ - _id: userId, - }), - organization: expect.objectContaining({ - _id: organizationId, - }), - allDay: false, - recurring: false, - isPublic: true, - isRegisterable: true, - status: 'ACTIVE', - }) - ); - const removeEventArgs = { - id: eventId, - }; - await removeEvent({}, removeEventArgs, context); - }); - - test('api call should return an error event not found', async () => { - // query that event - const response = await axios.post(URL, { - query: ` - query { - event (id: "${eventId}"){ - _id - } - } - `, - }); - const { data } = response; - // check the event now. - expect(data).toEqual( - expect.objectContaining({ - errors: expect.objectContaining([ - { - message: 'Event not found', - status: 422, - data: [ - { - message: 'Event not found', - code: 'event.notFound', - param: 'event', - metadata: {}, - }, - ], - }, - ]), - data: expect.objectContaining({ - event: null, - }), - }) - ); - }); - - test('api call should return a cast error', async () => { - // query that event - const invalidId = '1'; - const response = await axios.post(URL, { - query: ` - query { - event (id: ${invalidId}){ - _id - } - } - `, - }); - const { data } = response; - // check the event now. - expect(data).toEqual( - expect.objectContaining({ - errors: expect.objectContaining([ - { - message: `Cast to ObjectId failed for value "${invalidId}" (type string) at path "_id" for model "Event"`, - status: 422, - data: [], - }, - ]), - data: expect.objectContaining({ - event: null, - }), - }) - ); - }); -}); diff --git a/tests/resolver_tests/organization_mutations/createOrganization.spec.js b/tests/resolver_tests/organization_mutations/createOrganization.spec.js deleted file mode 100644 index 0605e8cd85..0000000000 --- a/tests/resolver_tests/organization_mutations/createOrganization.spec.js +++ /dev/null @@ -1,133 +0,0 @@ -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const database = require('../../../db'); -const shortid = require('shortid'); -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Create Organization Mutation', async () => { - // SignUp the User - const nameForNewUser = shortid.generate().toLowerCase(); - const email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - const context = { - userId: signUpResponse.user._id.toString(), - }; - const createOrgResponse = await createOrganization({}, args, context); - - expect(createOrgResponse).toMatchObject({ - status: 'ACTIVE', - groupChats: [], - posts: [], - membershipRequests: [], - blockedUsers: [], - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - image: null, - }); - - createOrgResponse.members.map((member) => { - expect(member).toMatchObject({ - __v: 0, - _id: signUpResponse.user._id, - adminFor: [], - appLanguageCode: 'en', - email: signUpResponse.user.email, - createdEvents: [], - createdOrganizations: [], - eventAdmin: [], - firstName: signUpResponse.user.firstName, - lastName: signUpResponse.user.lastName, - image: null, - joinedOrganizations: [], - membershipRequests: [], - organizationUserBelongsTo: null, - organizationsBlockedBy: [], - pluginCreationAllowed: true, - registeredEvents: [], - status: 'ACTIVE', - tokenVersion: 0, - userType: 'USER', - }); - }); - createOrgResponse.admins.map((admin) => { - expect(admin).toMatchObject({ - __v: 0, - _id: signUpResponse.user._id, - adminFor: [], - appLanguageCode: 'en', - email: signUpResponse.user.email, - createdEvents: [], - createdOrganizations: [], - eventAdmin: [], - firstName: signUpResponse.user.firstName, - lastName: signUpResponse.user.lastName, - image: null, - joinedOrganizations: [], - membershipRequests: [], - organizationUserBelongsTo: null, - organizationsBlockedBy: [], - pluginCreationAllowed: true, - registeredEvents: [], - status: 'ACTIVE', - tokenVersion: 0, - userType: 'USER', - }); - }); - - expect(createOrgResponse.creator).toMatchObject({ - __v: 0, - _id: signUpResponse.user._id, - adminFor: [], - appLanguageCode: 'en', - email: signUpResponse.user.email, - createdEvents: [], - createdOrganizations: [], - eventAdmin: [], - firstName: signUpResponse.user.firstName, - lastName: signUpResponse.user.lastName, - image: null, - joinedOrganizations: [], - membershipRequests: [], - organizationUserBelongsTo: null, - organizationsBlockedBy: [], - pluginCreationAllowed: true, - registeredEvents: [], - status: 'ACTIVE', - tokenVersion: 0, - userType: 'USER', - }); - }); -}); diff --git a/tests/resolvers/admin_mutations/admin-remove-event.spec.js b/tests/resolvers/admin_mutations/admin-remove-event.spec.js deleted file mode 100644 index f787739a5b..0000000000 --- a/tests/resolvers/admin_mutations/admin-remove-event.spec.js +++ /dev/null @@ -1,209 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const database = require('../../../db'); -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const adminRemoveEvent = require('../../../lib/resolvers/admin_mutations/admin-remove-event'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Admin Remove Event Mutation without Existing Event', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: true, - isRegisterable: true, - recurring: true, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: true, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - args = { - eventId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await adminRemoveEvent({}, args, context); - }).rejects.toEqual(Error('Event not found')); - }); - - test('Admin Remove Event Mutation without User', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: true, - isRegisterable: true, - recurring: true, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: true, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - args = { - eventId: createEventResponse._id, - }; - - context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await adminRemoveEvent({}, args, context); - }).rejects.toEqual(Error('User not found')); - }); - - test('Admin Remove Event Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: true, - isRegisterable: true, - recurring: true, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: true, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - args = { - eventId: createEventResponse._id, - }; - - const adminRemoveEventResponse = await adminRemoveEvent({}, args, context); - - expect(adminRemoveEventResponse.title).toEqual('Talawa Conference Test'); - }); -}); diff --git a/tests/resolvers/admin_mutations/admin-remove-group-chat.spec.js b/tests/resolvers/admin_mutations/admin-remove-group-chat.spec.js deleted file mode 100644 index 8f6f82e243..0000000000 --- a/tests/resolvers/admin_mutations/admin-remove-group-chat.spec.js +++ /dev/null @@ -1,173 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const database = require('../../../db'); -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const adminRemoveGroupChat = require('../../../lib/resolvers/admin_mutations/admin-remove-group-chat'); -const createGroupChat = require('../../../lib/resolvers/group_chat_mutations/createGroupChat'); -const { CHAT_NOT_FOUND, USER_NOT_FOUND } = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Admin Remove Group Chat Mutation without existing GroupChat', async () => { - const args = { - groupId: mongoose.Types.ObjectId(), - }; - - const context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await adminRemoveGroupChat({}, args, context); - }).rejects.toEqual(Error(CHAT_NOT_FOUND)); - }); - - test('Admin Remove Group Chat Mutation without User', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - // SignUp another User for - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const newUserSignUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - title: 'title', - organizationId: createOrgResponse._id, - userIds: [signUpResponse.user._id, newUserSignUpResponse.user._id], - }, - }; - - const createGroupChatResponse = await createGroupChat({}, args, context); - - args = { - groupId: createGroupChatResponse._id.toString(), - }; - - context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await adminRemoveGroupChat({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Admin Remove Group Chat Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - // SignUp another User for - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const newUserSignUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - title: 'title', - organizationId: createOrgResponse._id, - userIds: [signUpResponse.user._id, newUserSignUpResponse.user._id], - }, - }; - - const createGroupChatResponse = await createGroupChat({}, args, context); - - args = { - groupId: createGroupChatResponse._id.toString(), - }; - - const adminRemoveGroupChatResponse = await adminRemoveGroupChat( - {}, - args, - context - ); - - expect(adminRemoveGroupChatResponse.title).toEqual('title'); - }); -}); diff --git a/tests/resolvers/admin_mutations/admin-remove-post.spec.js b/tests/resolvers/admin_mutations/admin-remove-post.spec.js deleted file mode 100644 index b5de9f6728..0000000000 --- a/tests/resolvers/admin_mutations/admin-remove-post.spec.js +++ /dev/null @@ -1,191 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const database = require('../../../db'); -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const adminRemovePost = require('../../../lib/resolvers/admin_mutations/admin-remove-post'); -const createPost = require('../../../lib/resolvers/post_mutations/createPost'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Admin Remove Post Mutation without Existing Post', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - postId: mongoose.Types.ObjectId(), - organizationId: createOrgResponse._id, - }; - - await expect(async () => { - await adminRemovePost({}, args, context); - }).rejects.toEqual(Error('Post not found')); - }); - - test('Admin Remove Post Mutation without Existing Organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - args = { - organizationId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await adminRemovePost({}, args, context); - }).rejects.toEqual(Error('Organization not found')); - }); - - test('Admin Remove Post Mutation without User', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - organizationId: createOrgResponse._id, - postId: mongoose.Types.ObjectId(), - }; - - context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await adminRemovePost({}, args, context); - }).rejects.toEqual(Error('User not found')); - }); - - test('Admin Remove Post Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - text: 'assa', - title: 'assa', - }, - }; - - const createPostResponse = await createPost({}, args, context); - - args = { - organizationId: createOrgResponse._id, - postId: createPostResponse._id, - }; - - const adminRemovePostResponse = await adminRemovePost({}, args, context); - - expect(adminRemovePostResponse.title).toEqual('assa'); - }); -}); diff --git a/tests/resolvers/admin_mutations/adminRequest.spec.js b/tests/resolvers/admin_mutations/adminRequest.spec.js deleted file mode 100644 index e73f736a12..0000000000 --- a/tests/resolvers/admin_mutations/adminRequest.spec.js +++ /dev/null @@ -1,124 +0,0 @@ -const mongoose = require('mongoose'); -const shortid = require('shortid'); -const { USER_NOT_AUTHORIZED, USER_NOT_FOUND } = require('../../../constants'); - -const database = require('../../../db'); -const User = require('../../../lib/models/User'); -const { - acceptAdmin, - rejectAdmin, -} = require('../../../lib/resolvers/admin_mutations/adminRequest'); -const getUserId = require('../../functions/getUserIdFromSignup'); - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing admin request resolver', () => { - test('Testing accept request', async () => { - const generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - const userId = await getUserId(generatedEmail); - - await User.findByIdAndUpdate({ _id: userId }, { userType: 'SUPERADMIN' }); - - const args = { - id: userId, - }; - - const response = await acceptAdmin({}, args, { - userId, - }); - - expect(response).toBeTruthy(); - }); - - test('Testing, when the loggedIn user is not SUPERADMIN in accept admin', async () => { - const generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - const userId = await getUserId(generatedEmail); - - const args = { - id: userId, - }; - - await expect(async () => { - await acceptAdmin({}, args, { - userId, - }); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Testing, when user is not found in accept admin', async () => { - const generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - const userId = await getUserId(generatedEmail); - - await User.findByIdAndUpdate({ _id: userId }, { userType: 'SUPERADMIN' }); - - const context = { - userId, - }; - - const args = { - id: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await acceptAdmin({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Testing reject request', async () => { - const generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - const userId = await getUserId(generatedEmail); - - await User.findByIdAndUpdate({ _id: userId }, { userType: 'SUPERADMIN' }); - - const args = { - id: userId, - }; - - const response = await rejectAdmin({}, args, { - userId, - }); - - expect(response).toBeTruthy(); - }); - - test('Testing, when the loggedIn user is not SUPERADMIN in reject admin', async () => { - const generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - const userId = await getUserId(generatedEmail); - - const args = { - id: userId, - }; - - await expect(async () => { - await rejectAdmin({}, args, { - userId, - }); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Testing, when user is not found in reject admin', async () => { - const generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - const userId = await getUserId(generatedEmail); - - await User.findByIdAndUpdate({ _id: userId }, { userType: 'SUPERADMIN' }); - - const context = { - userId, - }; - - const args = { - id: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await rejectAdmin({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); -}); diff --git a/tests/resolvers/admin_mutations/createAdmin.spec.js b/tests/resolvers/admin_mutations/createAdmin.spec.js deleted file mode 100644 index f29f8cb41d..0000000000 --- a/tests/resolvers/admin_mutations/createAdmin.spec.js +++ /dev/null @@ -1,341 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const database = require('../../../db'); -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const createAdmin = require('../../../lib/resolvers/admin_mutations/createAdmin'); -const joinPublicOrganization = require('../../../lib/resolvers/member_mutations/join_public_organization'); -const { - ORGANIZATION_NOT_FOUND, - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, - ORGANIZATION_MEMBER_NOT_FOUND, -} = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Create Admin Mutation without Existing Organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - args = { - data: { - organizationId: mongoose.Types.ObjectId(), - userId: signUpResponse.user._id, - }, - }; - - await expect(async () => { - await createAdmin({}, args, context); - }).rejects.toEqual(Error(ORGANIZATION_NOT_FOUND)); - }); - - test('Create Admin Mutation without Existing User', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: mongoose.Types.ObjectId(), - }, - }; - - await expect(async () => { - await createAdmin({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Create Admin Mutation when user is already the admin of the organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: signUpResponse.user._id, - }, - }; - - await expect(async () => { - await createAdmin({}, args, context); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Create Admin Mutation when user is not a member of the organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const newUsersignUpResponse = await signup({}, args); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: newUsersignUpResponse.user._id, - }, - }; - - await expect(async () => { - await createAdmin({}, args, context); - }).rejects.toEqual(Error(ORGANIZATION_MEMBER_NOT_FOUND)); - }); - - test('Create Admin Mutation when user is a creator of the organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: signUpResponse.user._id.toString(), - }, - }; - - await expect(async () => { - await createAdmin({}, args, context); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Create Admin Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - - const newUsersignUpResponse = await signup({}, args); - - args = { - organizationId: createOrgResponse._id, - }; - - context = { - userId: newUsersignUpResponse.user._id, - }; - - // User Should be in an Organization for being an Admin - await joinPublicOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: newUsersignUpResponse.user._id, - }, - }; - - context = { - userId: signUpResponse.user._id.toString(), - }; - const createAdminResponse = await createAdmin({}, args, context); - - expect(createAdminResponse.tokenVersion).toEqual(0); - expect(createAdminResponse.appLanguageCode).toEqual('en'); - expect(createAdminResponse.createdOrganizations).toEqual([]); - expect(createAdminResponse.createdEvents).toEqual([]); - expect(createAdminResponse.userType).toEqual('USER'); - expect(createAdminResponse.registeredEvents).toEqual([]); - expect(createAdminResponse.eventAdmin).toEqual([]); - expect(createAdminResponse.membershipRequests).toEqual([]); - expect(createAdminResponse.organizationsBlockedBy).toEqual([]); - expect(createAdminResponse.status).toEqual('ACTIVE'); - expect(createAdminResponse.pluginCreationAllowed).toEqual(true); - expect(createAdminResponse.firstName).toEqual(nameForNewUser); - expect(createAdminResponse.lastName).toEqual(nameForNewUser); - expect(createAdminResponse.email).toEqual(email); - expect(createAdminResponse.password).toEqual(null); - expect(createAdminResponse.organizationUserBelongsTo).toEqual(null); - expect(createAdminResponse.image).toEqual(null); - }); -}); diff --git a/tests/resolvers/admin_mutations/removeAdmin.spec.js b/tests/resolvers/admin_mutations/removeAdmin.spec.js deleted file mode 100644 index a783feaf31..0000000000 --- a/tests/resolvers/admin_mutations/removeAdmin.spec.js +++ /dev/null @@ -1,314 +0,0 @@ -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const database = require('../../../db'); -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const createAdmin = require('../../../lib/resolvers/admin_mutations/createAdmin'); -const removeAdmin = require('../../../lib/resolvers/admin_mutations/removeAdmin'); -const joinPublicOrganization = require('../../../lib/resolvers/member_mutations/join_public_organization'); -const { - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, - ORGANIZATION_NOT_FOUND, -} = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Remove Admin Mutation without Existing Organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - args = { - data: { - organizationId: mongoose.Types.ObjectId(), - userId: signUpResponse.user._id, - }, - }; - - await expect(async () => { - await removeAdmin({}, args, context); - }).rejects.toEqual(Error(ORGANIZATION_NOT_FOUND)); - }); - - test('Remove Admin Mutation without Existing User', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: mongoose.Types.ObjectId(), - }, - }; - - await expect(async () => { - await removeAdmin({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Remove Admin Mutation without User being an Admin', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - // SignUp a new User (without Admin Role) - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const newUserSignUpResponse = await signup({}, args); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: newUserSignUpResponse.user._id.toString(), - }, - }; - - await expect(async () => { - await removeAdmin({}, args, context); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Remove Admin Mutation when user is the creator of the organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: signUpResponse.user._id, - }, - }; - const removeAdminResponse = await removeAdmin({}, args, context); - - expect(removeAdminResponse.tokenVersion).toEqual(0); - expect(removeAdminResponse.appLanguageCode).toEqual('en'); - expect(removeAdminResponse.createdOrganizations).toHaveLength(1); - expect(removeAdminResponse.createdEvents).toEqual([]); - expect(removeAdminResponse.userType).toEqual('USER'); - expect(removeAdminResponse.registeredEvents).toEqual([]); - expect(removeAdminResponse.eventAdmin).toEqual([]); - expect(removeAdminResponse.membershipRequests).toEqual([]); - expect(removeAdminResponse.organizationsBlockedBy).toEqual([]); - expect(removeAdminResponse.status).toEqual('ACTIVE'); - expect(removeAdminResponse.pluginCreationAllowed).toEqual(true); - expect(removeAdminResponse.firstName).toEqual(nameForNewUser); - expect(removeAdminResponse.lastName).toEqual(nameForNewUser); - expect(removeAdminResponse.email).toEqual(email); - expect(removeAdminResponse.password).toEqual(null); - expect(removeAdminResponse.organizationUserBelongsTo).toEqual(null); - expect(removeAdminResponse.image).toEqual(null); - }); - - test('Remove Admin Mutation', async () => { - // SignUp the User for Creating an Organization - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = true; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - // SignUp a new User for making a new admin into the organization - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - - const newUsersignUpResponse = await signup({}, args); - - args = { - organizationId: createOrgResponse._id, - }; - - context = { - userId: newUsersignUpResponse.user._id, - }; - - // New User joining into the organization for being an admin - await joinPublicOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - userId: newUsersignUpResponse.user._id, - }, - }; - - context = { - userId: signUpResponse.user._id.toString(), - }; - - // To remove an Admin, first the user needs to be an Admin - await createAdmin({}, args, context); - - const removeAdminResponse = await removeAdmin({}, args, context); - - expect(removeAdminResponse.tokenVersion).toEqual(0); - expect(removeAdminResponse.appLanguageCode).toEqual('en'); - expect(removeAdminResponse.createdOrganizations).toEqual([]); - expect(removeAdminResponse.createdEvents).toEqual([]); - expect(removeAdminResponse.userType).toEqual('USER'); - expect(removeAdminResponse.registeredEvents).toEqual([]); - expect(removeAdminResponse.eventAdmin).toEqual([]); - expect(removeAdminResponse.membershipRequests).toEqual([]); - expect(removeAdminResponse.organizationsBlockedBy).toEqual([]); - expect(removeAdminResponse.status).toEqual('ACTIVE'); - expect(removeAdminResponse.pluginCreationAllowed).toEqual(true); - expect(removeAdminResponse.firstName).toEqual(nameForNewUser); - expect(removeAdminResponse.lastName).toEqual(nameForNewUser); - expect(removeAdminResponse.email).toEqual(email); - expect(removeAdminResponse.password).toEqual(null); - expect(removeAdminResponse.organizationUserBelongsTo).toEqual(null); - expect(removeAdminResponse.image).toEqual(null); - }); -}); diff --git a/tests/resolvers/auth_mutations/forgotPassword.spec.js b/tests/resolvers/auth_mutations/forgotPassword.spec.js deleted file mode 100644 index b41d1c9eca..0000000000 --- a/tests/resolvers/auth_mutations/forgotPassword.spec.js +++ /dev/null @@ -1,84 +0,0 @@ -const bcrypt = require('bcryptjs'); -const jwt = require('jsonwebtoken'); -const shortid = require('shortid'); -const { INVALID_OTP } = require('../../../constants'); - -const database = require('../../../db'); -const forgotPassword = require('../../../lib/resolvers/auth_mutations/forgotPassword'); -const getToken = require('../../functions/getToken'); - -let hashedOtp; -let otpToken; -let token; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - hashedOtp = await bcrypt.hash('12345', 10); - otpToken = jwt.sign( - { email: generatedEmail, otp: hashedOtp }, - process.env.ACCESS_TOKEN_SECRET, - { - expiresIn: '15m', - } - ); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing forgotPassword resolver', () => { - test('forgotPassword', async () => { - console.log(token); - - const args = { - data: { - userOtp: '12345', - newPassword: 'newPassword', - otpToken: otpToken, - }, - }; - - const response = await forgotPassword({}, args); - expect(response).toBeTruthy(); - }); - - test('Testing, when user otp is incorrect', async () => { - const args = { - data: { - userOtp: '54321', - newPassword: 'newPassword', - otpToken: otpToken, - }, - }; - - await expect(async () => { - await forgotPassword({}, args); - }).rejects.toEqual(Error(INVALID_OTP)); - }); - - test('Testing, when user email is incorrect', async () => { - const fakeOtpToken = jwt.sign( - { email: 'abc321@email.com', otp: hashedOtp }, - process.env.ACCESS_TOKEN_SECRET, - { - expiresIn: '15m', - } - ); - - const args = { - data: { - userOtp: '12345', - newPassword: 'newPassword', - otpToken: fakeOtpToken, - }, - }; - - const response = await forgotPassword({}, args); - expect(response).toBeFalsy(); - }); -}); diff --git a/tests/resolvers/auth_mutations/logout.spec.js b/tests/resolvers/auth_mutations/logout.spec.js deleted file mode 100644 index 97191d6685..0000000000 --- a/tests/resolvers/auth_mutations/logout.spec.js +++ /dev/null @@ -1,46 +0,0 @@ -const mongoose = require('mongoose'); -const shortid = require('shortid'); -const { USER_NOT_FOUND } = require('../../../constants'); - -const database = require('../../../db'); -const logout = require('../../../lib/resolvers/auth_mutations/logout'); -const getToken = require('../../functions/getToken'); -const getUserId = require('../../functions/getUserId'); - -let generatedEmail; -let userId; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - - generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - await getToken(generatedEmail); - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing logout resolver', () => { - test('Logout user', async () => { - const context = { - userId, - }; - - const response = await logout({}, {}, context); - - expect(response).toBeTruthy(); - }); - - test('Testing, when user is not found', async () => { - const context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await logout({}, {}, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); -}); diff --git a/tests/resolvers/auth_mutations/otp.spec.js b/tests/resolvers/auth_mutations/otp.spec.js deleted file mode 100644 index facb020998..0000000000 --- a/tests/resolvers/auth_mutations/otp.spec.js +++ /dev/null @@ -1,47 +0,0 @@ -const shortid = require('shortid'); -const { USER_NOT_FOUND, ERROR_IN_SENDING_MAIL } = require('../../../constants'); - -const database = require('../../../db'); -const otp = require('../../../lib/resolvers/auth_mutations/otp'); -const getToken = require('../../functions/getToken'); - -let generatedEmail; -let token; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - - generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing otp resolver', () => { - test('otp', async () => { - console.log(token); - - const args = { - data: { - email: generatedEmail, - }, - }; - - await expect(() => otp({}, args)).rejects.toEqual(ERROR_IN_SENDING_MAIL); - }); - - test('Testing, when user email is incorrect', async () => { - const args = { - data: { - email: 'abc4321@email.com', - }, - }; - - await expect(async () => { - await otp({}, args); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); -}); diff --git a/tests/resolvers/auth_mutations/recaptcha.spec.js b/tests/resolvers/auth_mutations/recaptcha.spec.js deleted file mode 100644 index 661782777f..0000000000 --- a/tests/resolvers/auth_mutations/recaptcha.spec.js +++ /dev/null @@ -1,14 +0,0 @@ -const recaptcha = require('../../../lib/resolvers/auth_mutations/recaptcha'); - -describe('Testing recaptcha resolver', () => { - test('recaptcha', async () => { - const args = { - data: { - recaptchaToken: 'dummyToken', - }, - }; - - const response = await recaptcha({}, args); - expect(response).toBeFalsy(); - }); -}); diff --git a/tests/resolvers/auth_mutations/saveFcmToken.spec.js b/tests/resolvers/auth_mutations/saveFcmToken.spec.js deleted file mode 100644 index 4d8643206e..0000000000 --- a/tests/resolvers/auth_mutations/saveFcmToken.spec.js +++ /dev/null @@ -1,46 +0,0 @@ -const mongoose = require('mongoose'); -const shortid = require('shortid'); -const { USER_NOT_FOUND } = require('../../../constants'); - -const database = require('../../../db'); -const saveFcmToken = require('../../../lib/resolvers/auth_mutations/saveFcmToken'); -const getToken = require('../../functions/getToken'); -const getUserId = require('../../functions/getUserId'); - -let generatedEmail; -let userId; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - - generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - await getToken(generatedEmail); - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing save fcm resolver', () => { - test('Save Fcm Token', async () => { - const context = { - userId, - }; - - const response = await saveFcmToken({}, {}, context); - - expect(response).toBeTruthy(); - }); - - test('Testing, when user is not found', async () => { - const context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await saveFcmToken({}, {}, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); -}); diff --git a/tests/resolvers/auth_query/checkAuth.spec.js b/tests/resolvers/auth_query/checkAuth.spec.js deleted file mode 100644 index 19eaff6249..0000000000 --- a/tests/resolvers/auth_query/checkAuth.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -const shortid = require('shortid'); - -const database = require('../../../db'); -const getUserId = require('../../functions/getUserIdFromSignup'); -const checkAuth = require('../../../lib/resolvers/auth_query/checkAuth'); - -let userId; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing check auth resolver', () => { - test('Testing if the user logged in or not', async () => { - const args = { - id: '62277875e904753262f99bc3', - }; - - const response = await checkAuth({}, args, { - userId: userId, - }); - - expect(response).toBeTruthy(); - }); -}); diff --git a/tests/resolvers/block_user_mutations/block_user.spec.js b/tests/resolvers/block_user_mutations/block_user.spec.js deleted file mode 100644 index 0916a2f134..0000000000 --- a/tests/resolvers/block_user_mutations/block_user.spec.js +++ /dev/null @@ -1,129 +0,0 @@ -const blockUser = require('../../../lib/resolvers/block_user_mutations/block_user'); -const shortid = require('shortid'); -const { - Types: { ObjectId }, -} = require('mongoose'); - -const database = require('../../../db'); -const getUserIdFromSignup = require('../../functions/getUserIdFromSignup'); -const User = require('../../../lib/models/User'); -const Organization = require('../../../lib/models/Organization'); -const { - ORGANIZATION_NOT_FOUND, - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -let mainOrganization; -let organizationId; -let mainOrganizationAdminId; - -let secondaryUserId; - -let normalUserId; - -beforeAll(async () => { - // we would have 3 users 1 is admin of mainOrganization, - // and 2 other users. - require('dotenv').config(); - await database.connect(); - - let mainOrganizationAdminEmail = `${shortid - .generate() - .toLowerCase()}@test.com`; - mainOrganizationAdminId = await getUserIdFromSignup( - mainOrganizationAdminEmail - ); - - let secondaryUserEmail = `${shortid.generate().toLowerCase()}@test.com`; - secondaryUserId = await getUserIdFromSignup(secondaryUserEmail); - - let normalUserEmail = `${shortid.generate().toLowerCase()}@test.com`; - normalUserId = await getUserIdFromSignup(normalUserEmail); - - const organization = new Organization({ - name: 'mainOrganization', - description: - 'mainOrganization for testing the postsByOrganization resolver', - isPublic: true, - visibileInSearch: true, - status: 'ACTIVE', - members: [], - admins: [mainOrganizationAdminId], - groupChats: [], - posts: [], - membershipRequests: [], - blockedUsers: [], - image: '', - creator: mainOrganizationAdminId, - }); - mainOrganization = await organization.save(); - organizationId = mainOrganization._id; -}); -afterAll(async () => { - // delete the organization - await Organization.findByIdAndDelete(mainOrganization._id); - // delete users - await User.findByIdAndDelete(mainOrganizationAdminId); - await User.findByIdAndDelete(secondaryUserId); - await User.findByIdAndDelete(normalUserId); - await database.disconnect(); -}); - -describe('block user tests', () => { - test("user isn't an admin of the org", async () => { - await expect(async () => { - await blockUser( - {}, - { organizationId, userId: normalUserId }, - { userId: secondaryUserId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - test("organization doesn't exist", async () => { - await expect(async () => { - await blockUser( - {}, - { organizationId: new ObjectId(), userId: normalUserId }, - { userId: mainOrganizationAdminId } - ); - }).rejects.toThrow(ORGANIZATION_NOT_FOUND); - }); - - test("user doesn't exist", async () => { - await expect(async () => { - await blockUser( - {}, - { organizationId, userId: new ObjectId() }, - { userId: mainOrganizationAdminId } - ); - }).rejects.toThrow(USER_NOT_FOUND); - }); - - test('a valid block request', async () => { - const receivedUser = await blockUser( - {}, - { organizationId, userId: normalUserId }, - { userId: mainOrganizationAdminId } - ); - expect(receivedUser._id.toString()).toEqual(normalUserId); - expect(receivedUser.organizationsBlockedBy[0]).toEqual(organizationId); - }); - - test('blocking an already blocked user', async () => { - await expect(async () => { - await blockUser( - {}, - { organizationId, userId: normalUserId }, - { userId: mainOrganizationAdminId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - - test('blockedUsers inside organization contains the blocked user', async () => { - const organization = await Organization.findById(organizationId); - - const blockedUsers = organization.blockedUsers; - expect(blockedUsers[0].toString()).toEqual(normalUserId); - }); -}); diff --git a/tests/resolvers/block_user_mutations/unblock_user.spec.js b/tests/resolvers/block_user_mutations/unblock_user.spec.js deleted file mode 100644 index 5f27ef9d36..0000000000 --- a/tests/resolvers/block_user_mutations/unblock_user.spec.js +++ /dev/null @@ -1,142 +0,0 @@ -const unblockUser = require('../../../lib/resolvers/block_user_mutations/unblock_user'); -const blockUser = require('../../../lib/resolvers/block_user_mutations/block_user'); -const shortid = require('shortid'); -const { - Types: { ObjectId }, -} = require('mongoose'); -const database = require('../../../db'); -const getUserIdFromSignup = require('../../functions/getUserIdFromSignup'); -const User = require('../../../lib/models/User'); -const Organization = require('../../../lib/models/Organization'); -const { - ORGANIZATION_NOT_FOUND, - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -let mainOrganization; -let organizationId; -let mainOrganizationAdminId; - -let secondaryUserId; - -let normalUserId; - -beforeAll(async () => { - // we would have 3 users 1 is admin of mainOrganization, - // and 2 other users. - require('dotenv').config(); - await database.connect(); - - let mainOrganizationAdminEmail = `${shortid - .generate() - .toLowerCase()}@test.com`; - mainOrganizationAdminId = await getUserIdFromSignup( - mainOrganizationAdminEmail - ); - - let secondaryUserEmail = `${shortid.generate().toLowerCase()}@test.com`; - secondaryUserId = await getUserIdFromSignup(secondaryUserEmail); - - let normalUserEmail = `${shortid.generate().toLowerCase()}@test.com`; - normalUserId = await getUserIdFromSignup(normalUserEmail); - - const organization = new Organization({ - name: 'mainOrganization', - description: - 'mainOrganization for testing the postsByOrganization resolver', - isPublic: true, - visibileInSearch: true, - status: 'ACTIVE', - members: [], - admins: [mainOrganizationAdminId], - groupChats: [], - posts: [], - membershipRequests: [], - blockedUsers: [], - image: '', - creator: mainOrganizationAdminId, - }); - mainOrganization = await organization.save(); - organizationId = mainOrganization._id; -}); -afterAll(async () => { - // delete the organization - await Organization.findByIdAndDelete(mainOrganization._id); - // delete users - await User.findByIdAndDelete(mainOrganizationAdminId); - await User.findByIdAndDelete(secondaryUserId); - await User.findByIdAndDelete(normalUserId); - await database.disconnect(); -}); - -describe('unblock user tests', () => { - test("user isn't the admin of the org", async () => { - await expect(async () => { - await unblockUser( - {}, - { organizationId, userId: normalUserId }, - { userId: secondaryUserId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - - test("organization doesn't exist", async () => { - await expect(async () => { - await unblockUser( - {}, - { organizationId: new ObjectId(), userId: normalUserId }, - { userId: mainOrganizationAdminId } - ); - }).rejects.toThrow(ORGANIZATION_NOT_FOUND); - }); - - test("user doesn't exist", async () => { - await expect(async () => { - await unblockUser( - {}, - { organizationId, userId: new ObjectId() }, - { userId: mainOrganizationAdminId } - ); - }).rejects.toThrow(USER_NOT_FOUND); - }); - - test('unblocking a non blocked user', async () => { - await expect(async () => { - await unblockUser( - {}, - { organizationId, userId: normalUserId }, - { userId: mainOrganizationAdminId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - - test('a valid unblock request', async () => { - await blockUser( - {}, - { organizationId, userId: normalUserId }, - { userId: mainOrganizationAdminId } - ); - - const unblockUserResponse = await unblockUser( - {}, - { organizationId, userId: normalUserId }, - { userId: mainOrganizationAdminId } - ); - - const organization = unblockUserResponse.organizationsBlockedBy.find( - (org) => org._id === mainOrganization._id - ); - expect(unblockUserResponse._id.toString()).toEqual(normalUserId); - expect(organization).toEqual(undefined); - }); - - test('blockedUsers inside organization does not contain the unblocked user', async () => { - const organization = await Organization.findById(organizationId); - - const blockedUsers = organization.blockedUsers; - const blockedUser = blockedUsers.find((u) => u._id === normalUserId); - expect(blockedUser).toBeFalsy(); - expect(blockedUser).toBe(undefined); - }); -}); diff --git a/tests/resolvers/direct_chat_mutations/createDirectChat.spec.js b/tests/resolvers/direct_chat_mutations/createDirectChat.spec.js deleted file mode 100644 index 11466c5f5e..0000000000 --- a/tests/resolvers/direct_chat_mutations/createDirectChat.spec.js +++ /dev/null @@ -1,234 +0,0 @@ -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const createDirectChat = require('../../../lib/resolvers/direct_chat_mutations/createDirectChat'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const database = require('../../../db'); -const shortid = require('shortid'); -const mongoose = require('mongoose'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Create Direct Chat Mutation without User', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id.toString(), - userIds: [], - }, - }; - - // Removed User from Context with random ObjectID to check Line 11 in Unit Test - context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await createDirectChat({}, args, context); - }).rejects.toEqual(Error('User not found')); - }); - - test('Create Direct Chat Mutation without Organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - - const signUpResponse = await signup({}, args); - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - // Organization is removed in the args to check Line 21 in Unit Test - args = { - data: { - organizationId: mongoose.Types.ObjectId(), - userIds: [], - }, - }; - - await expect(async () => { - await createDirectChat({}, args, context); - }).rejects.toEqual(Error('Organization not Found')); - }); - - test('Create Direct Chat Mutation without Chat Users', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - // Removed Users of chat with Random ObjectID to check Line 36 in Unit Test - args = { - data: { - organizationId: createOrgResponse._id.toString(), - userIds: [mongoose.Types.ObjectId(), mongoose.Types.ObjectId()], - }, - }; - await expect(async () => { - await createDirectChat({}, args, context); - }).rejects.toEqual(Error('User not found')); - }); - - test('Create Direct Chat Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - // Creating Two Additional users for Chat - - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const user1 = await signup({}, args); - - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - - const user2 = await signup({}, args); - - args = { - data: { - organizationId: createOrgResponse._id.toString(), - userIds: [user1.user._id.toString(), user2.user._id.toString()], - }, - }; - - const response = await createDirectChat({}, args, context); - - response.users.map((user) => { - expect(user.tokenVersion).toEqual(0); - expect(user.appLanguageCode).toEqual('en'); - expect(user.createdOrganizations).toEqual([]); - expect(user.createdEvents).toEqual([]); - expect(user.userType).toEqual('USER'); - expect(user.joinedOrganizations).toEqual([]); - expect(user.registeredEvents).toEqual([]); - expect(user.eventAdmin).toEqual([]); - expect(user.adminFor).toEqual([]); - expect(user.membershipRequests).toEqual([]); - expect(user.organizationsBlockedBy).toEqual([]); - expect(user.status).toEqual('ACTIVE'); - expect(user.pluginCreationAllowed).toEqual(true); - expect(user.organizationUserBelongsTo).toEqual(null); - }); - expect(response.messages).toEqual([]); - expect(response.status).toEqual('ACTIVE'); - }); -}); diff --git a/tests/resolvers/direct_chat_mutations/sendMessageToDirectChat.spec.js b/tests/resolvers/direct_chat_mutations/sendMessageToDirectChat.spec.js deleted file mode 100644 index 5bd4a89dae..0000000000 --- a/tests/resolvers/direct_chat_mutations/sendMessageToDirectChat.spec.js +++ /dev/null @@ -1,170 +0,0 @@ -const axios = require('axios'); -const shortid = require('shortid'); -const { URL, CHAT_NOT_FOUND } = require('../../../constants'); -const getToken = require('../../functions/getToken'); -const getUserId = require('../../functions/getUserId'); -const sendMessageToDirectChat = require('../../../lib/resolvers/direct_chat_mutations/sendMessageToDirectChat'); -const database = require('../../../db'); -const mongoose = require('mongoose'); -const { PubSub } = require('apollo-server-express'); - -const pubsub = new PubSub(); // creating a new pubsub for passing to context in sendMessageToDirectChat -let token; -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); - require('dotenv').config(); // pull env variables from .env file - await database.connect(); // connect the database before running any test in this file's scope -}); - -afterAll(() => { - database.disconnect(); // disconnect the database after running every test in this file's scope -}); - -describe('tests for sendMessageToDirectChat', () => { - let createdDirectChatId; - let createdOrgId; - - test('create direct chat', async () => { - // CREATE AN ORGANIZATION - - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - - // CREATE A NEW USER - const nameForNewUser = shortid.generate(); - const email = `${nameForNewUser}@test.com`; - - const createNewUserResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForNewUser}", - lastName:"${nameForNewUser}" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = createNewUserResponse.data; - const newUserId = signUpData.data.signUp.user._id; - - // CREATE DIRECT CHAT - - const createDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - createDirectChat(data: { - organizationId: "${createdOrgId}" - userIds: ["${userId}", "${newUserId}"] - }){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const createDirectChatData = createDirectChatResponse.data; - createdDirectChatId = createDirectChatData.data.createDirectChat._id; - expect(createDirectChatData.data.createDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // SEND A MESSAGE TO A DIRECT CHAT - - test('send message to direct chat', async () => { - const sendMessageToDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMessageToDirectChat(chatId: "${createdDirectChatId}", messageContent: "this is a test message"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const sendMessageToADirectChatData = sendMessageToDirectChatResponse.data; - expect(sendMessageToADirectChatData.data.sendMessageToDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // if chat not found , throw error - test('if no Chat is found for the provided args.chatId, throws NotFoundError', async () => { - // Random id to pass as chat id - const args = { chatId: mongoose.Types.ObjectId() }; - - await expect(async () => { - await sendMessageToDirectChat({}, args); - }).rejects.toEqual(Error(CHAT_NOT_FOUND)); - }); - - // test for add message to chat in sendMessageToDirectChat - test('add message to chat', async () => { - var args = { - chatId: createdDirectChatId, - messageContent: 'This is a test message', - }; - const context = { - userId: userId, - pubsub: pubsub, - }; - const response = await sendMessageToDirectChat({}, args, context); - expect(response).toEqual( - expect.objectContaining({ - messageContent: expect.any(String), - }) - ); - }); -}); diff --git a/tests/resolvers/direct_chat_query/chatsbychatID.spec.js b/tests/resolvers/direct_chat_query/chatsbychatID.spec.js deleted file mode 100644 index db6f0016b7..0000000000 --- a/tests/resolvers/direct_chat_query/chatsbychatID.spec.js +++ /dev/null @@ -1,153 +0,0 @@ -const axios = require('axios'); -const shortid = require('shortid'); -const { URL } = require('../../../constants'); -const getToken = require('../../functions/getToken'); -const getUserId = require('../../functions/getUserId'); -const directChatsMessagesByChatID = require('../../../lib/resolvers/direct_chat_query/directChatsMessagesByChatID'); -const database = require('../../../db'); -// jest.useFakeTimers(); - -let token; -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); - require('dotenv').config(); - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('tests for direct chats by chat id', () => { - let createdDirectChatId; - let createdOrgId; - - test('create direct chat', async () => { - // CREATE AN ORGANIZATION - - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - - // CREATE A NEW USER - const nameForNewUser = shortid.generate(); - const email = `${nameForNewUser}@test.com`; - - const createNewUserResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForNewUser}", - lastName:"${nameForNewUser}" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = createNewUserResponse.data; - const newUserId = signUpData.data.signUp.user._id; - - // CREATE DIRECT CHAT - - const createDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - createDirectChat(data: { - organizationId: "${createdOrgId}" - userIds: ["${userId}", "${newUserId}"] - }){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const createDirectChatData = createDirectChatResponse.data; - createdDirectChatId = createDirectChatData.data.createDirectChat._id; - expect(createDirectChatData.data.createDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // SEND A MESSAGE TO A DIRECT CHAT - - test('send message to direct chat', async () => { - const sendMessageToDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMessageToDirectChat(chatId: "${createdDirectChatId}", messageContent: "this is a test message"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const sendMessageToADirectChatData = sendMessageToDirectChatResponse.data; - expect(sendMessageToADirectChatData.data.sendMessageToDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - //test for finding a direct chat by chat id - test('find chat by chat id', async () => { - var args = { - id: createdDirectChatId, - }; - const response = await directChatsMessagesByChatID({}, args); - expect(response[0]).toEqual( - expect.objectContaining({ - messageContent: expect.any(String), - }) - ); - }); -}); diff --git a/tests/resolvers/direct_chat_query/directChatMessages.spec.js b/tests/resolvers/direct_chat_query/directChatMessages.spec.js deleted file mode 100644 index f2457a78bb..0000000000 --- a/tests/resolvers/direct_chat_query/directChatMessages.spec.js +++ /dev/null @@ -1,24 +0,0 @@ -const directChatMessages = require('../../../lib/resolvers/direct_chat_query/directChatMessages'); -const database = require('../../../db'); - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('tests for direct chat messages', () => { - test('find direct chat messages', async () => { - let response = await directChatMessages(); - response.forEach((res) => { - expect(res).toEqual( - expect.objectContaining({ - messageContent: expect.any(String), - }) - ); - }); - }); -}); diff --git a/tests/resolvers/direct_chat_query/directChatsByUserID.spec.js b/tests/resolvers/direct_chat_query/directChatsByUserID.spec.js deleted file mode 100644 index 84ac1648ef..0000000000 --- a/tests/resolvers/direct_chat_query/directChatsByUserID.spec.js +++ /dev/null @@ -1,142 +0,0 @@ -const mongoose = require('mongoose'); -const bcrypt = require('bcryptjs'); -const shortid = require('shortid'); -const database = require('../../../db'); -const directChatsByUserID = require('../../../lib/resolvers/direct_chat_query/directChatsByUserID'); -const User = require('../../../lib/models/User'); -const Organization = require('../../../lib/models/Organization'); -const DirectChat = require('../../../lib/models/DirectChat'); - -let testUser1; -let testUser2; - -let testOrganization; - -let testDirectChat; - -const createUser = async () => { - const email = `${shortid.generate().toLowerCase()}@test.com`; - const hashedPassword = await bcrypt.hash('password', 12); - - const newUser = new User({ - email, - password: hashedPassword, - firstName: 'firstName', - lastName: 'lastName', - appLanguageCode: 'en', - image: null, - }); - - const createdUser = await newUser.save(); - - return createdUser; -}; - -const createOrganization = async (user) => { - const name = `organization_${shortid.generate().toLowerCase()}`; - - const newOrganization = new Organization({ - name, - description: 'description', - isPublic: true, - visibleInSearch: true, - apiUrl: 'https://organization.org', - image: null, - creator: user, - admins: [user], - members: [user], - }); - - const createdOrganization = await newOrganization.save(); - - await User.findOneAndUpdate( - { _id: user.id }, - { - $set: { - joinedOrganizations: [ - ...user._doc.joinedOrganizations, - createdOrganization, - ], - createdOrganizations: [ - ...user._doc.createdOrganizations, - createdOrganization, - ], - adminFor: [...user._doc.adminFor, createdOrganization], - }, - } - ); - - return createdOrganization; -}; - -const createDirectChat = async (user, users, organization) => { - const newDirectChat = new DirectChat({ - creator: user, - users, - organization, - }); - - const createdDirectChat = await newDirectChat.save(); - - return createdDirectChat; -}; - -// Read this :- https://jestjs.io/docs/api#beforeallfn-timeout -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); // connect the database before running any test in this file's scope - - testUser1 = await createUser(); - testUser2 = await createUser(); - - testOrganization = await createOrganization(testUser1); - - testDirectChat = await createDirectChat( - testUser1, - [testUser1, testUser2], - testOrganization - ); -}); - -// Read this :- https://jestjs.io/docs/api#afterallfn-timeout -afterAll(() => { - database.disconnect(); // disconnect the database after running every test in this file's scope -}); - -/* This test uses two users, one organization created by one of created users, one directChat created by the same user who owns the created organization. - In the first test it tests the resolver for a randomly generated userId. - In the second test it tests the resolver to return an array with exactly one directChat object(the directChat object created for this test).*/ - -describe('directChatsByUserID query resolver', () => { - test('if no directChats are found for the provided args.id, throws NotFoundError', async () => { - // Random id to pass as the user's id. - const args = { id: mongoose.Types.ObjectId() }; - - await expect(async () => { - await directChatsByUserID({}, args); - }).rejects.toEqual(Error('DirectChats not found')); - }); - - test('returns an array of all the directChats found for the provided args.id', async () => { - // Passing id of one of the users created for this test. - let args = { id: testUser1.id }; - - let result = await directChatsByUserID({}, args); - - expect(result).toHaveLength(1); - - expect(result).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - users: expect.arrayContaining([testUser1._id, testUser2._id]), - messages: expect.arrayContaining([]), - status: 'ACTIVE', - _id: testDirectChat._id, - creator: testUser1._id, - organization: testOrganization._id, - __v: 0, - }), - ]) - ); - }); -}); diff --git a/tests/resolvers/direct_chat_query/directChatsMessagesByChatID.spec.js b/tests/resolvers/direct_chat_query/directChatsMessagesByChatID.spec.js deleted file mode 100644 index 2fb874860a..0000000000 --- a/tests/resolvers/direct_chat_query/directChatsMessagesByChatID.spec.js +++ /dev/null @@ -1,163 +0,0 @@ -const axios = require('axios'); -const shortid = require('shortid'); -const { URL, CHAT_NOT_FOUND } = require('../../../constants'); -const getToken = require('../../functions/getToken'); -const getUserId = require('../../functions/getUserId'); -const directChatsMessagesByChatID = require('../../../lib/resolvers/direct_chat_query/directChatsMessagesByChatID'); -const database = require('../../../db'); -const mongoose = require('mongoose'); - -let token; -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); - require('dotenv').config(); // pull env variables from .env file - await database.connect(); // connect the database before running any test in this file's scope -}); - -afterAll(() => { - database.disconnect(); // disconnect the database after running every test in this file's scope -}); - -describe('tests for direct chats by chat id', () => { - let createdDirectChatId; - let createdOrgId; - - test('create direct chat', async () => { - // CREATE AN ORGANIZATION - - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - - // CREATE A NEW USER - const nameForNewUser = shortid.generate(); - const email = `${nameForNewUser}@test.com`; - - const createNewUserResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForNewUser}", - lastName:"${nameForNewUser}" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = createNewUserResponse.data; - const newUserId = signUpData.data.signUp.user._id; - - // CREATE DIRECT CHAT - - const createDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - createDirectChat(data: { - organizationId: "${createdOrgId}" - userIds: ["${userId}", "${newUserId}"] - }){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const createDirectChatData = createDirectChatResponse.data; - createdDirectChatId = createDirectChatData.data.createDirectChat._id; - expect(createDirectChatData.data.createDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // SEND A MESSAGE TO A DIRECT CHAT - - test('send message to direct chat', async () => { - const sendMessageToDirectChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - sendMessageToDirectChat(chatId: "${createdDirectChatId}", messageContent: "this is a test message"){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const sendMessageToADirectChatData = sendMessageToDirectChatResponse.data; - expect(sendMessageToADirectChatData.data.sendMessageToDirectChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // test for if no chats found , throw error - test('if no direct Chats are found for the provided args.id, throws NotFoundError', async () => { - // Random id to pass as chat id - const args = { id: mongoose.Types.ObjectId() }; - - await expect(async () => { - await directChatsMessagesByChatID({}, args); - }).rejects.toEqual(Error(CHAT_NOT_FOUND)); - }); - - // test for finding a direct chat by chat id - test('find chat by chat id', async () => { - var args = { - id: createdDirectChatId, - }; - const response = await directChatsMessagesByChatID({}, args); - expect(response[0]).toEqual( - expect.objectContaining({ - messageContent: expect.any(String), - }) - ); - }); -}); diff --git a/tests/resolvers/event_mutations/createEvent.spec.js b/tests/resolvers/event_mutations/createEvent.spec.js deleted file mode 100644 index 5e31254ae4..0000000000 --- a/tests/resolvers/event_mutations/createEvent.spec.js +++ /dev/null @@ -1,277 +0,0 @@ -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const database = require('../../../db'); -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const { - USER_NOT_FOUND, - ORGANIZATION_NOT_AUTHORIZED, - ORGANIZATION_NOT_FOUND, -} = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Create Event Mutation without user', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: true, - isRegisterable: true, - recurring: true, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: true, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - // Removed User from Context - context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await createEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Create Event Mutation without Organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - // Organization not created and random ID present in the args - args = { - data: { - organizationId: mongoose.Types.ObjectId(), - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: true, - isRegisterable: true, - recurring: true, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: true, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - await expect(async () => { - await createEvent({}, args, context); - }).rejects.toEqual(Error(ORGANIZATION_NOT_FOUND)); - }); - - test('Create Event Mutation with the user not present in the Organization', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - let signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - signUpResponse = await signup({}, args); - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: true, - isRegisterable: true, - recurring: true, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: true, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - context = { - userId: signUpResponse.user._id.toString(), - }; - - await expect(async () => { - await createEvent({}, args, context); - }).rejects.toEqual(Error(ORGANIZATION_NOT_AUTHORIZED)); - }); - - test('Create Event Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const response = await createEvent({}, args, context); - - expect(response.status).toEqual('ACTIVE'); - expect(response.title).toEqual('Talawa Conference Test'); - expect(response.description).toEqual( - 'National conference that happens yearly' - ); - expect(response.isPublic).toEqual(event_isPublic_boolean); - expect(response.isRegisterable).toEqual(event_isRegisterable_boolean); - expect(response.recurring).toEqual(event_recurring_boolean); - expect(response.recurrance).toEqual('YEARLY'); - expect(response.location).toEqual('Test'); - expect(response.startDate).toEqual('2/2/2020'); - expect(response.allDay).toEqual(event_allDay_boolean); - expect(response.startTime).toEqual('1:00 PM'); - expect(response.endTime).toEqual('2:00 PM'); - expect(response.creator).toEqual(signUpResponse.user._id); - expect(response.organization).toEqual(createOrgResponse._id); - }); -}); diff --git a/tests/resolvers/event_mutations/registerForEvent.spec.js b/tests/resolvers/event_mutations/registerForEvent.spec.js deleted file mode 100644 index 5865662d43..0000000000 --- a/tests/resolvers/event_mutations/registerForEvent.spec.js +++ /dev/null @@ -1,235 +0,0 @@ -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const registerForEvent = require('../../../lib/resolvers/event_mutations/registerForEvent'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const { - USER_NOT_FOUND, - REGISTRANT_ALREADY_EXIST, - EVENT_NOT_FOUND, -} = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Register for Event Mutation without user', async () => { - //Random Id for User - const context = { - userId: mongoose.Types.ObjectId(), - }; - - const args = { - id: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await registerForEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Register Event Mutation without Existing event', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - // Event hasn't been created and random ID present in the args - args = { - id: mongoose.Types.ObjectId(), - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - await expect(async () => { - await registerForEvent({}, args, context); - }).rejects.toEqual(Error(EVENT_NOT_FOUND)); - }); - - test('Register Event Mutation with user (Admin) already registered', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const response = await createEvent({}, args, context); - - args = { - id: response._id, - }; - - await expect(async () => { - await registerForEvent({}, args, context); - }).rejects.toEqual(Error(REGISTRANT_ALREADY_EXIST)); - }); - - test('Register Event Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - - const newUserSignUpResponse = await signup({}, args); - - context = { - userId: newUserSignUpResponse.user._id.toString(), - }; - - args = { - id: createEventResponse._id, - }; - - const response = await registerForEvent({}, args, context); - - expect(response.status).toEqual('ACTIVE'); - expect(response.title).toEqual('Talawa Conference Test'); - expect(response.description).toEqual( - 'National conference that happens yearly' - ); - expect(response.isPublic).toEqual(event_isPublic_boolean); - expect(response.isRegisterable).toEqual(event_isRegisterable_boolean); - expect(response.recurring).toEqual(event_recurring_boolean); - expect(response.recurrance).toEqual('YEARLY'); - expect(response.location).toEqual('Test'); - expect(response.startDate).toEqual('2/2/2020'); - expect(response.allDay).toEqual(event_allDay_boolean); - expect(response.startTime).toEqual('1:00 PM'); - expect(response.endTime).toEqual('2:00 PM'); - expect(response.creator).toEqual(signUpResponse.user._id); - expect(response.organization).toEqual(createOrgResponse._id); - }); -}); diff --git a/tests/resolvers/event_mutations/removeEvent.spec.js b/tests/resolvers/event_mutations/removeEvent.spec.js deleted file mode 100644 index aae371f7b5..0000000000 --- a/tests/resolvers/event_mutations/removeEvent.spec.js +++ /dev/null @@ -1,233 +0,0 @@ -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const removeEvent = require('../../../lib/resolvers/event_mutations/removeEvent'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const { - USER_NOT_FOUND, - EVENT_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Remove Event Mutation without Existing User', async () => { - const context = { - userId: mongoose.Types.ObjectId(), - }; - - const args = { - id: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await removeEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Register Event Mutation without Existing event', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - // Event not created and random ID present in the args - args = { - id: mongoose.Types.ObjectId(), - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - await expect(async () => { - await removeEvent({}, args, context); - }).rejects.toEqual(Error(EVENT_NOT_FOUND)); - }); - - test('Remove Event Mutation without Admin of Org or Event', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - // SignUp the User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const secondUserSignUpResponse = await signup({}, args); - - args = { - id: createEventResponse._id, - }; - - context = { - userId: secondUserSignUpResponse.user._id.toString(), - }; - - await expect(async () => { - await removeEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Remove Event Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - args = { - id: createEventResponse._id, - }; - - const response = await removeEvent({}, args, context); - - expect(response.status).toEqual('ACTIVE'); - expect(response.title).toEqual('Talawa Conference Test'); - expect(response.description).toEqual( - 'National conference that happens yearly' - ); - expect(response.isPublic).toEqual(event_isPublic_boolean); - expect(response.isRegisterable).toEqual(event_isRegisterable_boolean); - expect(response.recurring).toEqual(event_recurring_boolean); - expect(response.recurrance).toEqual('YEARLY'); - expect(response.location).toEqual('Test'); - expect(response.startDate).toEqual('2/2/2020'); - expect(response.allDay).toEqual(event_allDay_boolean); - expect(response.startTime).toEqual('1:00 PM'); - expect(response.endTime).toEqual('2:00 PM'); - expect(response.creator).toEqual(signUpResponse.user._id); - expect(response.organization).toEqual(createOrgResponse._id); - }); -}); diff --git a/tests/resolvers/event_mutations/unregisterForEvent.spec.js b/tests/resolvers/event_mutations/unregisterForEvent.spec.js deleted file mode 100644 index 5c6d1c8d36..0000000000 --- a/tests/resolvers/event_mutations/unregisterForEvent.spec.js +++ /dev/null @@ -1,349 +0,0 @@ -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const registerForEvent = require('../../../lib/resolvers/event_mutations/registerForEvent'); -const unregisterForEvent = require('../../../lib/resolvers/event_mutations/unregisterForEvent'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const { - EVENT_NOT_FOUND, - USER_NOT_FOUND, - USER_ALREADY_UNREGISTERED, -} = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Unregister for Event Mutation without user', async () => { - //Random Id for User - const context = { - userId: mongoose.Types.ObjectId(), - }; - - const args = { - id: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await unregisterForEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Unregister Event Mutation without Existing event', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - // Event hasn't been created and random ID present in the args - args = { - id: mongoose.Types.ObjectId(), - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - await expect(async () => { - await unregisterForEvent({}, args, context); - }).rejects.toEqual(Error(EVENT_NOT_FOUND)); - }); - - test('Unregister Event Mutation without user registered', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const newUserSignUpResponse = await signup({}, args); - - args = { - id: createEventResponse._id, - }; - - context = { - userId: newUserSignUpResponse.user._id.toString(), - }; - - await expect(async () => { - await unregisterForEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Unregister Event Mutation when user already unregistered', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - - const newUserSignUpResponse = await signup({}, args); - - context = { - userId: newUserSignUpResponse.user._id.toString(), - }; - - args = { - id: createEventResponse._id, - }; - - // Register for an event before unregistering - await registerForEvent({}, args, context); - - // Unregister for an event after registering - await unregisterForEvent({}, args, context); - - // Calling Unregister Mutation again after unregistering an event - await expect(async () => { - await unregisterForEvent({}, args, context); - }).rejects.toEqual(Error(USER_ALREADY_UNREGISTERED)); - }); - - test('Unregister Event Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - - const newUserSignUpResponse = await signup({}, args); - - context = { - userId: newUserSignUpResponse.user._id.toString(), - }; - - args = { - id: createEventResponse._id, - }; - - // Register for an event before unregistering - await registerForEvent({}, args, context); - - const response = await unregisterForEvent({}, args, context); - - expect(response.status).toEqual('ACTIVE'); - expect(response.title).toEqual('Talawa Conference Test'); - expect(response.description).toEqual( - 'National conference that happens yearly' - ); - expect(response.isPublic).toEqual(event_isPublic_boolean); - expect(response.isRegisterable).toEqual(event_isRegisterable_boolean); - expect(response.recurring).toEqual(event_recurring_boolean); - expect(response.recurrance).toEqual('YEARLY'); - expect(response.location).toEqual('Test'); - expect(response.startDate).toEqual('2/2/2020'); - expect(response.allDay).toEqual(event_allDay_boolean); - expect(response.startTime).toEqual('1:00 PM'); - expect(response.endTime).toEqual('2:00 PM'); - expect(response.creator).toEqual(signUpResponse.user._id); - expect(response.organization).toEqual(createOrgResponse._id); - }); -}); diff --git a/tests/resolvers/event_mutations/updateEvent.spec.js b/tests/resolvers/event_mutations/updateEvent.spec.js deleted file mode 100644 index 5a309e1739..0000000000 --- a/tests/resolvers/event_mutations/updateEvent.spec.js +++ /dev/null @@ -1,246 +0,0 @@ -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const updateEvent = require('../../../lib/resolvers/event_mutations/updateEvent'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const { - USER_NOT_FOUND, - EVENT_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Update Event Mutation without user', async () => { - //Random Id for User - const context = { - userId: mongoose.Types.ObjectId(), - }; - - const args = { - id: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await updateEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); - - test('Update Event Mutation without Existing event', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - // Event hasn't been created and random ID present in the args - args = { - id: mongoose.Types.ObjectId(), - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - await expect(async () => { - await updateEvent({}, args, context); - }).rejects.toEqual(Error(EVENT_NOT_FOUND)); - }); - - test('Update Event Mutation without user being an Admin', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - // SignUp a new User - nameForNewUser = shortid.generate().toLowerCase(); - email = `${nameForNewUser}@test.com`; - args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const newUserSignUpResponse = await signup({}, args); - - args = { - id: createEventResponse._id, - }; - - context = { - userId: newUserSignUpResponse.user._id.toString(), - }; - - await expect(async () => { - await updateEvent({}, args, context); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Update Event Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - let context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - args = { - id: createEventResponse._id, - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference', - description: 'National conference', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '3/3/2020', - endDate: '3/3/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - const response = await updateEvent({}, args, context); - - expect(response.status).toEqual('ACTIVE'); - expect(response.title).toEqual('Talawa Conference'); - expect(response.description).toEqual('National conference'); - expect(response.isPublic).toEqual(event_isPublic_boolean); - expect(response.isRegisterable).toEqual(event_isRegisterable_boolean); - expect(response.recurring).toEqual(event_recurring_boolean); - expect(response.recurrance).toEqual('YEARLY'); - expect(response.location).toEqual('Test'); - expect(response.startDate).toEqual('3/3/2020'); - expect(response.allDay).toEqual(event_allDay_boolean); - expect(response.startTime).toEqual('1:00 PM'); - expect(response.endTime).toEqual('2:00 PM'); - expect(response.creator).toEqual(signUpResponse.user._id); - expect(response.organization).toEqual(createOrgResponse._id); - }); -}); diff --git a/tests/resolvers/event_project_mutations/createProject.spec.js b/tests/resolvers/event_project_mutations/createProject.spec.js deleted file mode 100644 index 4b008ff21c..0000000000 --- a/tests/resolvers/event_project_mutations/createProject.spec.js +++ /dev/null @@ -1,93 +0,0 @@ -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const database = require('../../../db'); -const createProject = require('../../../lib/resolvers/event_project_mutations/createProject'); - -const { - eventProjectTestMutationHelpers, -} = require('./helpers/helperFunctions'); - -let user; -let user2; -let org; -let event; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - - user = await eventProjectTestMutationHelpers.createUser(); - user2 = await eventProjectTestMutationHelpers.createUser(); - if (user) { - org = await eventProjectTestMutationHelpers.createOrganization(user._id); - if (org) { - event = await eventProjectTestMutationHelpers.createEvent( - user._id, - org._id - ); - } - } -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('event_project_mutation createProject mutation resolver', () => { - test('when user not exists', async () => { - const context = { userId: mongoose.Types.ObjectId() }; - await expect(async () => { - await createProject({}, {}, context); - }).rejects.toThrow('User not found'); - }); - test('when Event not exists', async () => { - const context = { userId: user._id }; - const args = { - data: { - eventId: mongoose.Types.ObjectId(), - }, - }; - await expect(async () => { - await createProject({}, args, context); - }).rejects.toThrow('Event not found'); - }); - test('when user is not event admin', async () => { - const context = { userId: user2._id }; - const args = { - data: { - eventId: event._id, - }, - }; - await expect(async () => { - await createProject({}, args, context); - }).rejects.toThrow('User not Authorized'); - }); - test('Event project creation', async () => { - const context = { userId: user._id }; - const data = { - title: `test_event_project_${shortid.generate().toLowerCase()}`, - description: `testEventProjectDescription_${shortid - .generate() - .toLowerCase()}`, - eventId: event._id, - }; - - const args = { - data, - }; - const createdProject = await createProject({}, args, context); - expect(createdProject).toEqual( - expect.objectContaining({ - tasks: expect.arrayContaining([]), - title: data.title, - description: data.description, - event: expect.objectContaining({ - _id: data.eventId, - }), - creator: expect.objectContaining({ - _id: user._id, - }), - }) - ); - }); -}); diff --git a/tests/resolvers/event_project_mutations/helpers/helperFunctions.js b/tests/resolvers/event_project_mutations/helpers/helperFunctions.js deleted file mode 100644 index 70bea53532..0000000000 --- a/tests/resolvers/event_project_mutations/helpers/helperFunctions.js +++ /dev/null @@ -1,104 +0,0 @@ -const shortid = require('shortid'); -const bcrypt = require('bcryptjs'); -const User = require('../../../../lib/models/User'); -const Organization = require('../../../../lib/models/Organization'); -const Event = require('../../../../lib/models/Event'); -const EventProject = require('../../../../lib/models/EventProject'); - -async function createUser() { - const email = `${shortid.generate().toLowerCase()}@test.com`; - const hashedPassword = await bcrypt.hash('password', 10); - - const newUser = new User({ - email, - password: hashedPassword, - firstName: 'firstName', - lastName: 'lastName', - appLanguageCode: 'en', - }); - - const createdUser = await newUser.save(); - - return createdUser; -} - -async function createOrganization(userId) { - const name = `test_org_${shortid.generate().toLowerCase()}`; - - const newOrganization = new Organization({ - name, - description: `test_org_description_${shortid.generate().toLowerCase()}`, - isPublic: true, - visibleInSearch: true, - creator: userId, - admins: [userId], - members: [userId], - }); - - const createdOrganization = await newOrganization.save(); - - await User.findByIdAndUpdate(userId, { - $set: { - joinedOrganizations: [createdOrganization._id], - createdOrganizations: [createdOrganization._id], - adminFor: [createdOrganization._id], - }, - }); - - return createdOrganization; -} - -async function createEvent(userId, organizationId) { - const newEvent = new Event({ - title: `test_event_${shortid.generate().toLowerCase()}`, - description: `testEventDescription_${shortid.generate().toLowerCase()}`, - startDate: new Date(), - allDay: true, - recurring: true, - isPublic: true, - isRegisterable: true, - creator: userId, - registrants: [ - { - userId: userId, - user: userId, - }, - ], - admins: [userId], - organization: organizationId, - }); - - const createdEvent = await newEvent.save(); - - await User.findByIdAndUpdate(userId, { - $push: { - eventAdmin: createdEvent._id, - createdEvents: createdEvent._id, - registeredEvents: createdEvent._id, - }, - }); - - return createdEvent; -} - -async function createEventProject(userId, eventId) { - const newEventProject = new EventProject({ - title: `test_event_project_${shortid.generate().toLowerCase()}`, - description: `testEventProjectDescription_${shortid - .generate() - .toLowerCase()}`, - event: eventId, - creator: userId, - }); - - const createdEventProject = await newEventProject.save(); - - return createdEventProject; -} - -exports.eventProjectTestMutationHelpers = { - createEventProject, - createEvent, - createUser, - createOrganization, -}; diff --git a/tests/resolvers/event_project_mutations/removeProject.spec.js b/tests/resolvers/event_project_mutations/removeProject.spec.js deleted file mode 100644 index 3db911436c..0000000000 --- a/tests/resolvers/event_project_mutations/removeProject.spec.js +++ /dev/null @@ -1,90 +0,0 @@ -const mongoose = require('mongoose'); -const database = require('../../../db'); -const removeProject = require('../../../lib/resolvers/event_project_mutations/removeProject'); - -const { - eventProjectTestMutationHelpers, -} = require('./helpers/helperFunctions'); - -const { - USER_NOT_AUTHORIZED, - USER_NOT_FOUND, - EVENT_PROJECT_NOT_FOUND, -} = require('../../../constants'); -let user; -let user2; -let org; -let event; -let eventProject; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - - user = await eventProjectTestMutationHelpers.createUser(); - user2 = await eventProjectTestMutationHelpers.createUser(); - if (user) { - org = await eventProjectTestMutationHelpers.createOrganization(user._id); - if (org) { - event = await eventProjectTestMutationHelpers.createEvent( - user._id, - org._id - ); - if (event) { - eventProject = await eventProjectTestMutationHelpers.createEventProject( - user._id, - event._id - ); - } - } - } -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('event_project_mutation removeProject mutation resolver', () => { - test('when user not exists', async () => { - const context = { userId: mongoose.Types.ObjectId() }; - await expect(async () => { - await removeProject({}, {}, context); - }).rejects.toThrow(USER_NOT_FOUND); - }); - test('EventProject not exists', async () => { - const context = { userId: user._id }; - const args = { - id: mongoose.Types.ObjectId(), - }; - await expect(async () => { - await removeProject({}, args, context); - }).rejects.toThrow(EVENT_PROJECT_NOT_FOUND); - }); - test('when user is not event creator', async () => { - const context = { userId: user2._id }; - const args = { - id: eventProject._id, - }; - await expect(async () => { - await removeProject({}, args, context); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - test('Event project delete/remove', async () => { - const context = { userId: `${user._id}` }; - const args = { - id: eventProject._id, - }; - - const removedProject = await removeProject({}, args, context); - expect(removedProject).toEqual( - expect.objectContaining({ - tasks: expect.arrayContaining([]), - title: eventProject.title, - description: eventProject.description, - event: eventProject.event, - creator: user._id, - status: eventProject.status, - }) - ); - }); -}); diff --git a/tests/resolvers/event_project_mutations/updateProject.spec.js b/tests/resolvers/event_project_mutations/updateProject.spec.js deleted file mode 100644 index 64b5060503..0000000000 --- a/tests/resolvers/event_project_mutations/updateProject.spec.js +++ /dev/null @@ -1,200 +0,0 @@ -const mongoose = require('mongoose'); -const bcrypt = require('bcryptjs'); -const shortid = require('shortid'); -const database = require('../../../db'); -const updateProject = require('../../../lib/resolvers/event_project_mutations/updateProject'); -const User = require('../../../lib/models/User'); -const Organization = require('../../../lib/models/Organization'); -const Event = require('../../../lib/models/Event'); -const EventProject = require('../../../lib/models/EventProject'); - -let testUser1; - -let testUser2; - -let testOrganization; - -let testEvent; - -let testEventProject; - -const createUser = async () => { - const email = `${shortid.generate().toLowerCase()}@test.com`; - const hashedPassword = await bcrypt.hash('password', 12); - - const newUser = new User({ - email, - password: hashedPassword, - firstName: 'firstName', - lastName: 'lastName', - appLanguageCode: 'en', - image: null, - }); - - const createdUser = await newUser.save(); - - return createdUser; -}; - -const createOrganization = async (user) => { - const name = `organization_${shortid.generate().toLowerCase()}`; - - const newOrganization = new Organization({ - name, - description: 'testOrganizationDescription', - isPublic: true, - visibleInSearch: true, - apiUrl: `https://${name}.org`, - image: null, - creator: user, - admins: [user], - members: [user], - }); - - const createdOrganization = await newOrganization.save(); - - await User.findOneAndUpdate( - { _id: user.id }, - { - $set: { - joinedOrganizations: [ - ...user._doc.joinedOrganizations, - createdOrganization, - ], - createdOrganizations: [ - ...user._doc.createdOrganizations, - createdOrganization, - ], - adminFor: [...user._doc.adminFor, createdOrganization], - }, - } - ); - - return createdOrganization; -}; - -const createEvent = async (userId, organizationId) => { - const newEvent = new Event({ - title: 'testEventTitle', - description: 'testEventDescription', - startDate: '26 March, 2122', - allDay: true, - recurring: true, - isPublic: true, - isRegisterable: true, - creator: userId, - registrants: [ - { - userId: userId, - user: userId, - }, - ], - admins: [userId], - organization: organizationId, - }); - - const createdEvent = await newEvent.save(); - - await User.updateOne( - { _id: userId }, - { - $push: { - eventAdmin: newEvent, - createdEvents: newEvent, - registeredEvents: newEvent, - }, - } - ); - - return createdEvent; -}; - -const createEventProject = async (user, event) => { - const newEventProject = new EventProject({ - title: 'testEventProjectTitle', - description: 'testEventProjectDescription', - event, - creator: user, - }); - - const createdEventProject = await newEventProject.save(); - - return createdEventProject; -}; - -// Read this :- https://jestjs.io/docs/api#beforeallfn-timeout -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); // connect the database before running any test in this file's scope - - testUser1 = await createUser(); - - testUser2 = await createUser(); - - testOrganization = await createOrganization(testUser1); - - testEvent = await createEvent(testUser1._id, testOrganization._id); - - testEventProject = await createEventProject(testUser1, testEvent); -}); - -// Read this :- https://jestjs.io/docs/api#afterallfn-timeout -afterAll(() => { - database.disconnect(); // disconnect the database after running every test in this file's scope -}); - -/* This test uses two users, one organization created by one of those users, - one event created by that user, one eventProject created by that user. */ - -describe('updateProject mutation resolver', () => { - test('if no user is found the provided context.userId, throws NotFoundError', async () => { - const context = { userId: mongoose.Types.ObjectId() }; - - await expect(async () => { - await updateProject({}, {}, context); - }).rejects.toEqual(Error('User not found')); - }); - - test('if no eventProject is found for the provided args.id, throws NotFoundError', async () => { - const args = { id: mongoose.Types.ObjectId() }; - const context = { userId: testUser1._id }; - - await expect(async () => { - await updateProject({}, args, context); - }).rejects.toEqual(Error('EventProject not found')); - }); - - test('if user with id=context.userId is not the creator of eventProject with id=args.id, throws UnauthorizedError', async () => { - const args = { id: testEventProject.id }; - const context = { userId: testUser2.id }; - - await expect(async () => { - await updateProject({}, args, context); - }).rejects.toEqual(Error('User not authorized')); - }); - - test('on successful execution, returns the updated eventProject', async () => { - const data = { - title: 'newTestEventProjectTitle', - description: 'newTestEventProjectDescription', - }; - const args = { id: testEventProject.id, data }; - const context = { userId: testUser1.id }; - - const result = await updateProject({}, args, context); - - expect(result).toEqual( - expect.objectContaining({ - tasks: expect.arrayContaining([]), - status: 'ACTIVE', - _id: testEventProject._id, - title: data.title, - description: data.description, - event: testEvent._id, - creator: testUser1._id, - createdAt: testEventProject.createdAt, - __v: testEventProject.__v, - }) - ); - }); -}); diff --git a/tests/resolvers/event_query/events.spec.js b/tests/resolvers/event_query/events.spec.js deleted file mode 100644 index a51db32378..0000000000 --- a/tests/resolvers/event_query/events.spec.js +++ /dev/null @@ -1,71 +0,0 @@ -const eventsQuery = require('../../../lib/resolvers/event_query/events'); -const database = require('../../../db'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - const orderByArgs = [ - 'id_ASC', - 'id_DESC', - 'title_ASC', - 'title_DESC', - 'description_ASC', - 'description_DESC', - 'startDate_ASC', - 'startDate_DESC', - 'endDate_ASC', - 'endDate_DESC', - 'allDay_ASC', - 'allDay_DESC', - 'startTime_ASC', - 'startTime_DESC', - 'endTime_ASC', - 'endTime_DESC', - 'recurrance_ASC', - 'recurrance_DESC', - 'location_ASC', - 'location_DESC', - ]; - - orderByArgs.map((arg) => { - test(`Events Query with orderBy ${arg}`, async () => { - const args = { - orderBy: arg, - }; - const response = await eventsQuery({}, args); - response.map((event) => { - expect(typeof event.status === 'string').toBeTruthy(); - expect(typeof event.title === 'string').toBeTruthy(); - expect(typeof event.description === 'string').toBeTruthy(); - expect(typeof event.isPublic === 'boolean').toBeTruthy(); - expect(typeof event.isRegisterable === 'boolean').toBeTruthy(); - expect(typeof event.recurring === 'boolean').toBeTruthy(); - expect(typeof event.recurrance === 'string').toBeTruthy(); - expect( - typeof event.location === 'string' || - event.location === null || - event.location === undefined - ).toBeTruthy(); - expect(typeof event.startDate === 'string').toBeTruthy(); - expect(typeof event.allDay === 'boolean').toBeTruthy(); - expect( - typeof event.startTime === 'string' || - event.startTime === null || - event.startTime === undefined - ).toBeTruthy(); - expect( - typeof event.endTime === 'string' || - event.endTime === null || - event.endTime === undefined - ).toBeTruthy(); - }); - }); - }); -}); diff --git a/tests/resolvers/event_query/eventsByOrganization.spec.js b/tests/resolvers/event_query/eventsByOrganization.spec.js deleted file mode 100644 index 6634b4a3db..0000000000 --- a/tests/resolvers/event_query/eventsByOrganization.spec.js +++ /dev/null @@ -1,122 +0,0 @@ -const shortid = require('shortid'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const eventsByOrganization = require('../../../lib/resolvers/event_query/eventsByOrganization'); -let createOrgResponse; -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - await createEvent({}, args, context); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - const orderByArgs = [ - 'id_ASC', - 'id_DESC', - 'title_ASC', - 'title_DESC', - 'description_ASC', - 'description_DESC', - 'startDate_ASC', - 'startDate_DESC', - 'endDate_ASC', - 'endDate_DESC', - 'allDay_ASC', - 'allDay_DESC', - 'startTime_ASC', - 'startTime_DESC', - 'endTime_ASC', - 'endTime_DESC', - 'recurrance_ASC', - 'recurrance_DESC', - 'location_ASC', - 'location_DESC', - ]; - - orderByArgs.map((arg) => { - test(`Events By Organization Query with orderBy ${arg}`, async () => { - let args = { - orderBy: arg, - id: createOrgResponse._id, - }; - - const response = await eventsByOrganization({}, args); - response.map((event) => { - expect(event.title).toEqual('Talawa Conference Test'); - expect(event.description).toEqual( - 'National conference that happens yearly' - ); - expect(event.status).toEqual('ACTIVE'); - expect(event.recurrance).toEqual('YEARLY'); - expect(event.location).toEqual('Test'); - expect(event.startDate).toEqual('2/2/2020'); - expect(event.endDate).toEqual('2/2/2022'); - expect(event.endTime).toEqual('2:00 PM'); - expect(event.startTime).toEqual('1:00 PM'); - }); - }); - }); -}); diff --git a/tests/resolvers/event_query/isUserRegister.spec.js b/tests/resolvers/event_query/isUserRegister.spec.js deleted file mode 100644 index 2f91669087..0000000000 --- a/tests/resolvers/event_query/isUserRegister.spec.js +++ /dev/null @@ -1,121 +0,0 @@ -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const isUserRegister = require('../../../lib/resolvers/event_query/isUserRegister'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const { EVENT_NOT_FOUND } = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Is User Register Mutation without Event', async () => { - // Random Id inside args for throwing errors - const args = { - eventId: mongoose.Types.ObjectId(), - }; - - // No need of user as it the mutation throws error before itself. - const context = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await isUserRegister({}, args, context); - }).rejects.toEqual(Error(EVENT_NOT_FOUND)); - }); - - test('Is User Register Mutation', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - args = { - eventId: createEventResponse._id, - }; - - const response = await isUserRegister({}, args, context); - - // As User is an Admin of org and creator of the event, default will be isRegistered as true. - expect(response.isRegistered).toEqual(true); - - expect(response.event.status).toEqual('ACTIVE'); - expect(response.event.title).toEqual('Talawa Conference Test'); - expect(response.event.description).toEqual( - 'National conference that happens yearly' - ); - expect(response.event.isPublic).toEqual(event_isPublic_boolean); - expect(response.event.isRegisterable).toEqual(event_isRegisterable_boolean); - expect(response.event.recurring).toEqual(event_recurring_boolean); - expect(response.event.recurrance).toEqual('YEARLY'); - expect(response.event.location).toEqual('Test'); - expect(response.event.startDate).toEqual('2/2/2020'); - expect(response.event.allDay).toEqual(event_allDay_boolean); - expect(response.event.startTime).toEqual('1:00 PM'); - expect(response.event.endTime).toEqual('2:00 PM'); - expect(response.event.creator._id).toEqual(signUpResponse.user._id); - expect(response.event.organization).toEqual(createOrgResponse._id); - }); -}); diff --git a/tests/resolvers/event_query/registeredEventsByUser.spec.js b/tests/resolvers/event_query/registeredEventsByUser.spec.js deleted file mode 100644 index bf2b813958..0000000000 --- a/tests/resolvers/event_query/registeredEventsByUser.spec.js +++ /dev/null @@ -1,71 +0,0 @@ -const registeredEventsByUser = require('../../../lib/resolvers/event_query/registeredEventsByUser'); -const database = require('../../../db'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - const orderByArgs = [ - 'id_ASC', - 'id_DESC', - 'title_ASC', - 'title_DESC', - 'description_ASC', - 'description_DESC', - 'startDate_ASC', - 'startDate_DESC', - 'endDate_ASC', - 'endDate_DESC', - 'allDay_ASC', - 'allDay_DESC', - 'startTime_ASC', - 'startTime_DESC', - 'endTime_ASC', - 'endTime_DESC', - 'recurrance_ASC', - 'recurrance_DESC', - 'location_ASC', - 'location_DESC', - ]; - - orderByArgs.map((arg) => { - test(`Registered Events by User Query with orderBy ${arg}`, async () => { - const args = { - orderBy: arg, - }; - const response = await registeredEventsByUser({}, args); - response.map((event) => { - expect(typeof event.status === 'string').toBeTruthy(); - expect(typeof event.title === 'string').toBeTruthy(); - expect(typeof event.description === 'string').toBeTruthy(); - expect(typeof event.isPublic === 'boolean').toBeTruthy(); - expect(typeof event.isRegisterable === 'boolean').toBeTruthy(); - expect(typeof event.recurring === 'boolean').toBeTruthy(); - expect(typeof event.recurrance === 'string').toBeTruthy(); - expect( - typeof event.location === 'string' || - event.location === null || - event.location === undefined - ).toBeTruthy(); - expect(typeof event.startDate === 'string').toBeTruthy(); - expect(typeof event.allDay === 'boolean').toBeTruthy(); - expect( - typeof event.startTime === 'string' || - event.startTime === null || - event.startTime === undefined - ).toBeTruthy(); - expect( - typeof event.endTime === 'string' || - event.endTime === null || - event.endTime === undefined - ).toBeTruthy(); - }); - }); - }); -}); diff --git a/tests/resolvers/event_query/registrantsByEvent.spec.js b/tests/resolvers/event_query/registrantsByEvent.spec.js deleted file mode 100644 index 839b5c5d3b..0000000000 --- a/tests/resolvers/event_query/registrantsByEvent.spec.js +++ /dev/null @@ -1,107 +0,0 @@ -const shortid = require('shortid'); -const mongoose = require('mongoose'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const registrantsByEvent = require('../../../lib/resolvers/event_query/registrantsByEvent'); -const { EVENT_NOT_FOUND } = require('../../../constants'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - test('Registrants By Event Query without existing Event', async () => { - const args = { - id: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await registrantsByEvent({}, args); - }).rejects.toEqual(Error(EVENT_NOT_FOUND)); - }); - - test('Registrants By Event Query', async () => { - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - const createEventResponse = await createEvent({}, args, context); - - args = { - id: createEventResponse._id, - }; - - const response = await registrantsByEvent({}, args); - response.map((registrant) => { - expect(registrant.appLanguageCode).toEqual('en'); - expect(registrant.userType).toEqual('USER'); - expect(registrant.status).toEqual('ACTIVE'); - expect(registrant.pluginCreationAllowed).toEqual(true); - expect(typeof registrant.firstName === 'string').toBeTruthy(); - expect(typeof registrant.lastName === 'string').toBeTruthy(); - expect(typeof registrant.email === 'string').toBeTruthy(); - expect(registrant.password).toEqual(null); - expect(registrant.organizationUserBelongsTo).toEqual(null); - expect(registrant.image).toEqual(null); - }); - }); -}); diff --git a/tests/resolvers/event_query/tasksByEvent.spec.js b/tests/resolvers/event_query/tasksByEvent.spec.js deleted file mode 100644 index 4daf562316..0000000000 --- a/tests/resolvers/event_query/tasksByEvent.spec.js +++ /dev/null @@ -1,117 +0,0 @@ -const shortid = require('shortid'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const createTask = require('../../../lib/resolvers/project_task_mutations/createTask'); -const tasksByEvent = require('../../../lib/resolvers/event_query/tasksByEvent'); -let createEventResponse; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - const context = { - userId: signUpResponse.user._id.toString(), - }; - - const createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - createEventResponse = await createEvent({}, args, context); - - args = { - eventId: createEventResponse._id, - data: { - title: 'title', - description: 'description', - status: 'ACTIVE', - }, - }; - - await createTask({}, args, context); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Unit testing', () => { - const orderByArgs = [ - 'id_ASC', - 'id_DESC', - 'title_ASC', - 'title_DESC', - 'description_ASC', - 'description_DESC', - 'createdAt_ASC', - 'createdAt_DESC', - 'deadline_ASC', - 'deadline_DESC', - ]; - - orderByArgs.map((arg) => { - test(`Tasks By Event Query with orderBy ${arg}`, async () => { - let args = { - orderBy: arg, - id: createEventResponse._id, - }; - - const response = await tasksByEvent({}, args); - response.map((task) => { - expect(task.title).toEqual('title'); - expect(task.description).toEqual('description'); - expect(task.status).toEqual('ACTIVE'); - }); - }); - }); -}); diff --git a/tests/resolvers/group_chat_mutations/addUserToGroupChat.spec.js b/tests/resolvers/group_chat_mutations/addUserToGroupChat.spec.js deleted file mode 100644 index 5540419bee..0000000000 --- a/tests/resolvers/group_chat_mutations/addUserToGroupChat.spec.js +++ /dev/null @@ -1,179 +0,0 @@ -const axios = require('axios'); -const shortid = require('shortid'); -const { - URL, - USER_ALREADY_MEMBER, - CHAT_NOT_FOUND, -} = require('../../../constants'); -const getToken = require('../../functions/getToken'); -const getUserId = require('../../functions/getUserId'); -const addUserToGroupChat = require('../../../lib/resolvers/group_chat_mutations/addUserToGroupChat'); -const database = require('../../../db'); -const mongoose = require('mongoose'); - -let token; -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); - require('dotenv').config(); // pull env variables from .env file - await database.connect(); // connect the database before running any test in this file's scope -}); - -afterAll(() => { - database.disconnect(); // disconnect the database after running every test in this file's scope -}); - -describe('tests for adding a user to group chat', () => { - let createdGroupChatId; - let createdOrgId; - let newUserAddedId; - - // CREATE GROUP CHAT - test('create group chat', async () => { - // CREATE AN ORGANIZATION - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - - // CREATE A NEW USER - const nameForNewUser = shortid.generate(); - const email = `${nameForNewUser}@test.com`; - - const createNewUserResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForNewUser}", - lastName:"${nameForNewUser}" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = createNewUserResponse.data; - const newUserId = signUpData.data.signUp.user._id; - - // CREATE ANOTHER NEW USER TO ADD TO GROUP CHAT - const nameForUserBeingAdded = shortid.generate(); - const emailForUser = `${nameForUserBeingAdded}@test.com`; - - const createNewUserResponse1 = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForUserBeingAdded}", - lastName:"${nameForUserBeingAdded}" - email: "${emailForUser}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData1 = createNewUserResponse1.data; - newUserAddedId = signUpData1.data.signUp.user._id; - - const createGroupChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - createGroupChat(data: { - title: "This is a group chat for testing" - organizationId: "${createdOrgId}" - userIds: ["${userId}", "${newUserId}"] - }){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const createGroupChatData = createGroupChatResponse.data; - createdGroupChatId = createGroupChatData.data.createGroupChat._id; - - expect(createGroupChatData.data.createGroupChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // test if no groupchat exists - test('if no group Chat is found for the provided args.id, throws NotFoundError', async () => { - // Random id to pass as chat id - const args = { chatId: mongoose.Types.ObjectId() }; - const context = { userId: mongoose.Types.ObjectId() }; - await expect(async () => { - await addUserToGroupChat({}, args, context); - }).rejects.toEqual(Error(CHAT_NOT_FOUND)); - }); - - // test if user is already added - test('if user is already added,throws Error', async () => { - const args = { - chatId: createdGroupChatId, - userId: userId, - }; - const context = { userId: userId }; - await expect(async () => { - await addUserToGroupChat({}, args, context); - }).rejects.toEqual(Error(USER_ALREADY_MEMBER)); - }); - - // test for adding a user to group chat - test('add user to group chat', async () => { - var args = { - chatId: createdGroupChatId, - userId: newUserAddedId, // passing new user id whichwe created to add to group chat - }; - var context = { - userId: userId, - }; - const response = await addUserToGroupChat({}, args, context); - expect(response).toEqual( - expect.objectContaining({ - messages: expect.any(Array), - }) - ); - }); -}); diff --git a/tests/resolvers/group_chat_mutations/sendMessageToGroupChat.spec.js b/tests/resolvers/group_chat_mutations/sendMessageToGroupChat.spec.js deleted file mode 100644 index 57938a4cfa..0000000000 --- a/tests/resolvers/group_chat_mutations/sendMessageToGroupChat.spec.js +++ /dev/null @@ -1,190 +0,0 @@ -const axios = require('axios'); -const shortid = require('shortid'); -const { - URL, - USER_NOT_AUTHORIZED, - CHAT_NOT_FOUND, -} = require('../../../constants'); -const getToken = require('../../functions/getToken'); -const getUserId = require('../../functions/getUserId'); -const sendMessageToGroupChat = require('../../../lib/resolvers/group_chat_mutations/sendMessageToGroupChat'); -const database = require('../../../db'); -const mongoose = require('mongoose'); -const { PubSub } = require('apollo-server-express'); - -let token; -let userId; -const pubsub = new PubSub(); // creating a new pubsub for passing to context in sendMessageToDirectChat - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); - require('dotenv').config(); // pull env variables from .env file - await database.connect(); // connect the database before running any test in this file's scope -}); - -afterAll(() => { - database.disconnect(); // disconnect the database after running every test in this file's scope -}); - -describe('tests for sending a message to group chat', () => { - let createdGroupChatId; - let createdOrgId; - let newUser1Id; - - // CREATE GROUP CHAT - test('create group chat', async () => { - // CREATE AN ORGANIZATION - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - - // CREATE A NEW USER - const nameForNewUser = shortid.generate(); - const email = `${nameForNewUser}@test.com`; - - const createNewUserResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForNewUser}", - lastName:"${nameForNewUser}" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpData = createNewUserResponse.data; - const newUserId = signUpData.data.signUp.user._id; - - // CREATE ANOTHER USER WHICH IS NOT ADDED IN GROUP CHAT - const nameForUser1 = shortid.generate(); - const emailforUser1 = `${nameForUser1}@test.com`; - - const createUserResponseForUser1 = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"${nameForUser1}", - lastName:"${nameForUser1}" - email: "${emailforUser1}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const signUpDataForUser1 = createUserResponseForUser1.data; - newUser1Id = signUpDataForUser1.data.signUp.user._id; // new user id which is not the part of the groupchat - - const createGroupChatResponse = await axios.post( - URL, - { - query: ` - mutation{ - createGroupChat(data: { - title: "This is a group chat for testing" - organizationId: "${createdOrgId}" - userIds: ["${userId}", "${newUserId}"] - }){ - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const createGroupChatData = createGroupChatResponse.data; - createdGroupChatId = createGroupChatData.data.createGroupChat._id; - - expect(createGroupChatData.data.createGroupChat).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // TEST IF NO GROUP CHAT EXISTS - test('if no group Chat is found for the provided args.id, throws NotFoundError', async () => { - const args = { - chatId: mongoose.Types.ObjectId(), // Random id to pass as chat id - messageContent: 'This is a test message', - }; - const context = { - userId: mongoose.Types.ObjectId(), - pubsub: pubsub, - }; - await expect(async () => { - await sendMessageToGroupChat({}, args, context); - }).rejects.toEqual(Error(CHAT_NOT_FOUND)); - }); - - // TEST IF USER IS NOT A MEMBER OF THE GROUP CHAT - test('if user not a member of the group chat, throw Error', async () => { - const args = { - chatId: createdGroupChatId, - messageContent: 'This is a test message', - }; - const context = { - userId: newUser1Id, // passing new user id which is not the member of the group chat - pubsub: pubsub, - }; - await expect(async () => { - await sendMessageToGroupChat({}, args, context); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - // TEST FRO SENDING MESSAGE TO THE GROUP CHAT - test('send message to group chat', async () => { - var args = { - chatId: createdGroupChatId, - messageContent: 'This is a test message', - }; - var context = { - userId: userId, - pubsub: pubsub, - }; - const response = await sendMessageToGroupChat({}, args, context); - expect(response).toEqual( - expect.objectContaining({ - messageContent: 'This is a test message', - }) - ); - }); -}); diff --git a/tests/resolvers/group_chat_query/groupChatMessages.spec.js b/tests/resolvers/group_chat_query/groupChatMessages.spec.js deleted file mode 100644 index af70d0d291..0000000000 --- a/tests/resolvers/group_chat_query/groupChatMessages.spec.js +++ /dev/null @@ -1,24 +0,0 @@ -const groupChatMessageFindMethod = require('../../../lib/resolvers/group_chat_query/groupChatMessages'); -const database = require('../../../db'); - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); -describe('tests for lib/resolvers/group_chat_query/groupChatMessages.js', () => { - test('Should return a JSON response (getting the group chat messages from the database)', async () => { - expect(await groupChatMessageFindMethod()).toBeTruthy(); - }); - test('groupChatMessasges Produces metadata object that can be parsed to valid JSON', async () => { - const temp = await groupChatMessageFindMethod(); - const parseJson = () => { - const json = JSON.stringify(temp); - JSON.parse(json); - }; - expect(parseJson).not.toThrow(); - }); -}); diff --git a/tests/resolvers/group_chat_query/groupChats.spec.js b/tests/resolvers/group_chat_query/groupChats.spec.js deleted file mode 100644 index ce970e1827..0000000000 --- a/tests/resolvers/group_chat_query/groupChats.spec.js +++ /dev/null @@ -1,26 +0,0 @@ -const database = require('../../../db'); -const groupChat = require('../../../lib/resolvers/group_chat_query/groupChats'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(async () => { - database.disconnect(); -}); - -describe('tests for lib/resolvers/group_chat_query/groupChats.js', () => { - test('Should return a JSON response (getting the group chat messages from the database)', async () => { - const res = await groupChat(); - expect(typeof res).toBe('object'); - }); - test('groupChat Produces metadata object that can be parsed to valid JSON', async () => { - const temp = await groupChat(); - const parseJson = () => { - const json = JSON.stringify(temp); - JSON.parse(json); - }; - expect(parseJson).not.toThrow(); - }); -}); diff --git a/tests/resolvers/language_maintainer_mutation/addLanguageTranslation.spec.js b/tests/resolvers/language_maintainer_mutation/addLanguageTranslation.spec.js deleted file mode 100644 index 51e096dab1..0000000000 --- a/tests/resolvers/language_maintainer_mutation/addLanguageTranslation.spec.js +++ /dev/null @@ -1,119 +0,0 @@ -const languageTranslationMutation = require('../../../lib/resolvers/language_maintainer_mutation/addLanguageTranslation'); -const database = require('../../../db'); -const shortid = require('shortid'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -function getRandomInt(max) { - return Math.floor(Math.random() * max); -} - -describe('Language Mutation testing', () => { - const uniqueId = shortid.generate().toLowerCase(); - const enValue = `hello world ${uniqueId}`; - const translationInDiffLanguage = { - de: `hallo welt ${uniqueId}`, - en: `hello world ${uniqueId}`, - es: `hola mundo ${uniqueId}`, - fr: `bonjour le monde ${uniqueId}`, - hi: `नमस्ते दुनिया ${uniqueId}`, - ja: `こんにちは世界 ${uniqueId}`, - pt: `olá mundo ${uniqueId}`, - zh: `你好世界 ${uniqueId}`, - ur: `ہیلو دنیا ${uniqueId}`, - }; - const langCode = ['de', 'en', 'es', 'fr', 'hi', 'ja', 'pt', 'zh']; - const randomIndex = getRandomInt(8); - const getTranslationLangCode = langCode[randomIndex]; - - test('New Translation', async () => { - const translationLangCode = getTranslationLangCode; - - const args = { - data: { - en_value: enValue, - translation_lang_code: translationLangCode, - translation_value: translationInDiffLanguage[translationLangCode], - }, - }; - - const response = await languageTranslationMutation({}, args); - const finalResult = { - en: response.en, - }; - - response.translation.forEach((element) => { - if (element.lang_code === translationLangCode) { - finalResult['translation'] = { - lang_code: element.lang_code, - value: element.value, - }; - } - }); - - //NEW LANGUAGE PACKET ADDED - expect(finalResult).toEqual({ - en: enValue, - translation: { - lang_code: translationLangCode, - value: translationInDiffLanguage[translationLangCode], - }, - }); - }); - - test('New Translation in existing packet', async () => { - langCode[randomIndex] = 'ur'; - const newTranslationLangCode = langCode[getRandomInt(8)]; - const newArgs = { - data: { - en_value: enValue, - translation_lang_code: newTranslationLangCode, - translation_value: translationInDiffLanguage[newTranslationLangCode], - }, - }; - - const newResponse = await languageTranslationMutation({}, newArgs); - const newFinalResult = { - en: newResponse.en, - }; - - newResponse.translation.forEach((newElement) => { - if (newElement.lang_code === newTranslationLangCode) { - newFinalResult['translation'] = { - lang_code: newElement.lang_code, - value: newElement.value, - }; - } - }); - - expect(newFinalResult).toEqual({ - en: enValue, - translation: { - lang_code: newTranslationLangCode, - value: translationInDiffLanguage[newTranslationLangCode], - }, - }); - }); - - test('Translation already existing in packet', async () => { - const translationLangCode = getTranslationLangCode; - const newArgs = { - data: { - en_value: enValue, - translation_lang_code: translationLangCode, - translation_value: `${translationInDiffLanguage[translationLangCode]} 123`, - }, - }; - - await expect(async () => { - await languageTranslationMutation({}, newArgs); - }).rejects.toEqual(Error('Already Present')); - }); -}); diff --git a/tests/resolvers/language_maintainer_query/getlanguage.spec.js b/tests/resolvers/language_maintainer_query/getlanguage.spec.js deleted file mode 100644 index 6efd9e2382..0000000000 --- a/tests/resolvers/language_maintainer_query/getlanguage.spec.js +++ /dev/null @@ -1,60 +0,0 @@ -const getLanguageQuery = require('../../../lib/resolvers/language_maintainer_query/getlanguage'); -const languageTranslationMutation = require('../../../lib/resolvers/language_maintainer_mutation/addLanguageTranslation'); -const database = require('../../../db'); -const shortid = require('shortid'); - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - - const uniqueId = shortid.generate().toLowerCase(); - const enValue = `hello world ${uniqueId}`; - const translationInDiffLanguage = { - de: `hallo welt ${uniqueId}`, - en: `hello world ${uniqueId}`, - es: `hola mundo ${uniqueId}`, - fr: `bonjour le monde ${uniqueId}`, - hi: `नमस्ते दुनिया ${uniqueId}`, - ja: `こんにちは世界 ${uniqueId}`, - pt: `olá mundo ${uniqueId}`, - zh: `你好世界 ${uniqueId}`, - ur: `ہیلو دنیا ${uniqueId}`, - }; - const langCode = ['de', 'en', 'es', 'fr', 'hi', 'ja', 'pt', 'zh']; - const randomIndex = getRandomInt(8); - const getTranslationLangCode = langCode[randomIndex]; - const args = { - data: { - en_value: enValue, - translation_lang_code: getTranslationLangCode, - translation_value: translationInDiffLanguage[getTranslationLangCode], - }, - }; - - await languageTranslationMutation({}, args); -}); - -afterAll(() => { - database.disconnect(); -}); - -function getRandomInt(max) { - return Math.floor(Math.random() * max); -} - -describe('Language Query testing', () => { - const langCode = ['de', 'en', 'es', 'fr', 'hi', 'ja', 'pt', 'zh']; - const randomIndex = getRandomInt(8); - const getTranslationLangCode = langCode[randomIndex]; - - test('Get Translation', async () => { - const args = { - lang_code: getTranslationLangCode, - }; - - const response = await getLanguageQuery({}, args); - - //NEW LANGUAGE PACKET ADDED - expect(response).toEqual(expect.any(Array)); - }); -}); diff --git a/tests/resolvers/language_mutation/updateLanguage.spec.js b/tests/resolvers/language_mutation/updateLanguage.spec.js deleted file mode 100644 index 7cd06e6e44..0000000000 --- a/tests/resolvers/language_mutation/updateLanguage.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -const updateLanguageMutation = require('../../../lib/resolvers/language_mutation/updateLanguage'); -const database = require('../../../db'); -const shortid = require('shortid'); -const getUserId = require('../../functions/getUserIdFromSignup'); - -let userId; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -function getRandomInt(max) { - return Math.floor(Math.random() * max); -} - -describe('Language Mutation testing', () => { - const langCode = ['de', 'en', 'es', 'fr', 'hi', 'ja', 'pt', 'zh']; - const randomIndex = getRandomInt(8); - - test('New User Language Update', async () => { - const args = { - languageCode: langCode[randomIndex], - }; - - const response = await updateLanguageMutation({}, args, { - userId: userId, - }); - expect(response).toEqual( - expect.objectContaining({ - appLanguageCode: langCode[randomIndex], - }) - ); - }); - - test('User not exist in database language update', async () => { - const args = { - languageCode: langCode[randomIndex], - }; - - await expect(async () => { - await updateLanguageMutation({}, args, { - userId: '62277875e904753262f99ba9', - }); - }).rejects.toEqual(Error('User not found')); - }); -}); diff --git a/tests/resolvers/membership_request_mutations/accept_membership_request.spec.js b/tests/resolvers/membership_request_mutations/accept_membership_request.spec.js deleted file mode 100644 index cf436cbfdc..0000000000 --- a/tests/resolvers/membership_request_mutations/accept_membership_request.spec.js +++ /dev/null @@ -1,217 +0,0 @@ -const shortid = require('shortid'); -const acceptMembershipRequest = require('../../../lib/resolvers/membership_request_mutations/accept_membership_request'); -const { - Types: { ObjectId }, -} = require('mongoose'); - -const database = require('../../../db'); -const getUserIdFromSignUp = require('../../functions/getUserIdFromSignup'); -const Organization = require('../../../lib/models/Organization'); -const User = require('../../../lib/models/User'); -const MembershipRequest = require('../../../lib/models/MembershipRequest'); -const { - MEMBERSHIP_REQUEST_NOT_FOUND, - ORGANIZATION_NOT_FOUND, - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, - USER_ALREADY_MEMBER, -} = require('../../../constants'); - -let adminId; -let memberId; -let membershipRequesterId; - -let organizationId; -let validMembershipRequestId; -let invalidOrgMembershipRequestId; -let invalidUserMembershipRequestId; -let alreadyMemberMembershipRequestId; - -beforeAll(async () => { - // we need 1 org, 1 admin, 1 requester, 1 member - require('dotenv').config(); - await database.connect(); - - const adminEmail = `${shortid.generate().toLowerCase()}@test.com`; - adminId = await getUserIdFromSignUp(adminEmail); - - const memberEmail = `${shortid.generate().toLowerCase()}@test.com`; - memberId = await getUserIdFromSignUp(memberEmail); - - const membershipRequesterEmail = `${shortid - .generate() - .toLowerCase()}@test.com`; - membershipRequesterId = await getUserIdFromSignUp(membershipRequesterEmail); - - const organization = new Organization({ - name: 'an organization', - description: 'an organization for testing the removeOrganization resolver', - isPublic: true, - visibileInSearch: true, - status: 'ACTIVE', - members: [adminId, memberId], - admins: [adminId], - posts: [], - membershipRequests: [], - blockedUsers: [], - groupChats: [], - image: '', - creator: adminId, - }); - - const savedOrg = await organization.save(); - organizationId = savedOrg._id; - - const membershipRequest = new MembershipRequest({ - organization: organizationId, - user: membershipRequesterId, - }); - const invalidOrgMembershipRequest = new MembershipRequest({ - organization: new ObjectId(), - user: membershipRequesterId, - }); - const invalidUserMembershipRequest = new MembershipRequest({ - organization: organizationId, - user: new ObjectId(), - }); - const alreadyMemberMembershipRequest = new MembershipRequest({ - organization: organizationId, - user: memberId, - }); - - const savedMembershipRequest = await membershipRequest.save(); - validMembershipRequestId = savedMembershipRequest._id; - - const savedAlreadyMemberMembershipRequest = - await alreadyMemberMembershipRequest.save(); - alreadyMemberMembershipRequestId = savedAlreadyMemberMembershipRequest._id; - - const savedInvalidOrgMembershipRequest = - await invalidOrgMembershipRequest.save(); - invalidOrgMembershipRequestId = savedInvalidOrgMembershipRequest._id; - - const savedInvalidUserMembershipRequest = - await invalidUserMembershipRequest.save(); - invalidUserMembershipRequestId = savedInvalidUserMembershipRequest._id; - - const admin = await User.findById(adminId); - admin.overwrite({ - ...admin._doc, - joinedOrganizations: [organizationId], - createdOrganizations: [organizationId], - adminFor: [organizationId], - }); - await admin.save(); - - const member = await User.findById(memberId); - member.overwrite({ - ...member._doc, - joinedOrganizations: [organizationId], - }); - await member.save(); - - const membershipRequester = await User.findById(membershipRequesterId); - membershipRequester.overwrite({ - ...membershipRequester._doc, - membershipRequests: [validMembershipRequestId], - }); - await membershipRequester.save(); - - savedOrg.overwrite({ - ...savedOrg._doc, - membershipRequests: [validMembershipRequestId], - }); - await savedOrg.save(); -}); - -afterAll(async () => { - await User.findByIdAndDelete(adminId); - await User.findByIdAndDelete(membershipRequesterId); - await User.findByIdAndDelete(memberId); - - await Organization.findByIdAndDelete(organizationId); - await MembershipRequest.findByIdAndDelete(validMembershipRequestId); - await MembershipRequest.findByIdAndDelete(invalidOrgMembershipRequestId); - await MembershipRequest.findByIdAndDelete(invalidUserMembershipRequestId); - await MembershipRequest.findByIdAndDelete(alreadyMemberMembershipRequestId); - - await database.disconnect(); -}); - -describe('accept membership request', () => { - test("membership request doesn't exist", async () => { - await expect(async () => { - await acceptMembershipRequest( - {}, - { membershipRequestId: new ObjectId() }, - { userId: adminId } - ); - }).rejects.toThrow(MEMBERSHIP_REQUEST_NOT_FOUND); - }); - - test("organization doesn't exist", async () => { - await expect(async () => { - await acceptMembershipRequest( - {}, - { membershipRequestId: invalidOrgMembershipRequestId }, - { userId: adminId } - ); - }).rejects.toThrow(ORGANIZATION_NOT_FOUND); - }); - - test("user doesn't exist", async () => { - await expect(async () => { - await acceptMembershipRequest( - {}, - { membershipRequestId: invalidUserMembershipRequestId }, - { userId: adminId } - ); - }).rejects.toThrow(USER_NOT_FOUND); - }); - - test('user is not the admin of the org', async () => { - await expect(async () => { - await acceptMembershipRequest( - {}, - { membershipRequestId: validMembershipRequestId }, - { userId: memberId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - test('user is already a member', async () => { - await expect(async () => { - await acceptMembershipRequest( - {}, - { membershipRequestId: alreadyMemberMembershipRequestId }, - { userId: adminId } - ); - }).rejects.toThrow(USER_ALREADY_MEMBER); - }); - - test('a valid accept member', async () => { - const membershipRequest = await acceptMembershipRequest( - {}, - { membershipRequestId: validMembershipRequestId }, - { userId: adminId } - ); - const savedMembershipRequest = await MembershipRequest.findById( - validMembershipRequestId - ); - const org = await Organization.findById(organizationId); - const user = await User.findById(membershipRequesterId); - - expect(membershipRequest._id).toEqual(validMembershipRequestId); - expect(savedMembershipRequest).toBeFalsy(); - expect(org.membershipRequests.length).toBeFalsy(); - expect( - org.members - .find((member) => member._id.toString() === membershipRequesterId) - ._id.toString() - ).toBe(membershipRequesterId); - - expect(user.membershipRequests.length).toBeFalsy(); - expect(user.joinedOrganizations[0].toString()).toEqual( - organizationId.toString() - ); - }); -}); diff --git a/tests/resolvers/membership_request_mutations/cancel_membership_request.spec.js b/tests/resolvers/membership_request_mutations/cancel_membership_request.spec.js deleted file mode 100644 index e25205055b..0000000000 --- a/tests/resolvers/membership_request_mutations/cancel_membership_request.spec.js +++ /dev/null @@ -1,193 +0,0 @@ -const shortid = require('shortid'); -const cancelMembershipRequest = require('../../../lib/resolvers/membership_request_mutations/cancel_membership_request'); -const { - Types: { ObjectId }, -} = require('mongoose'); - -const database = require('../../../db'); -const getUserIdFromSignUp = require('../../functions/getUserIdFromSignup'); -const Organization = require('../../../lib/models/Organization'); -const User = require('../../../lib/models/User'); -const MembershipRequest = require('../../../lib/models/MembershipRequest'); -const { - MEMBERSHIP_REQUEST_NOT_FOUND, - ORGANIZATION_NOT_FOUND, - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -let adminId; -let memberId; -let membershipRequesterId; - -let organizationId; -let validMembershipRequestId; -let invalidOrgMembershipRequestId; -let invalidUserMembershipRequestId; -let alreadyMemberMembershipRequestId; - -beforeAll(async () => { - // we need 1 org, 1 admin, 1 requester, 1 member - require('dotenv').config(); - await database.connect(); - - const adminEmail = `${shortid.generate().toLowerCase()}@test.com`; - adminId = await getUserIdFromSignUp(adminEmail); - - const memberEmail = `${shortid.generate().toLowerCase()}@test.com`; - memberId = await getUserIdFromSignUp(memberEmail); - - const membershipRequesterEmail = `${shortid - .generate() - .toLowerCase()}@test.com`; - membershipRequesterId = await getUserIdFromSignUp(membershipRequesterEmail); - - const organization = new Organization({ - name: 'an organization', - description: 'an organization for testing the removeOrganization resolver', - isPublic: true, - visibileInSearch: true, - status: 'ACTIVE', - members: [adminId, memberId], - admins: [adminId], - posts: [], - membershipRequests: [], - blockedUsers: [], - groupChats: [], - image: '', - creator: adminId, - }); - - const savedOrg = await organization.save(); - organizationId = savedOrg._id; - - const membershipRequest = new MembershipRequest({ - organization: organizationId, - user: membershipRequesterId, - }); - const invalidOrgMembershipRequest = new MembershipRequest({ - organization: new ObjectId(), - user: membershipRequesterId, - }); - const invalidUserMembershipRequest = new MembershipRequest({ - organization: organizationId, - user: new ObjectId(), - }); - const alreadyMemberMembershipRequest = new MembershipRequest({ - organization: organizationId, - user: memberId, - }); - - const savedMembershipRequest = await membershipRequest.save(); - validMembershipRequestId = savedMembershipRequest._id; - - const savedAlreadyMemberMembershipRequest = - await alreadyMemberMembershipRequest.save(); - alreadyMemberMembershipRequestId = savedAlreadyMemberMembershipRequest._id; - - const savedInvalidOrgMembershipRequest = - await invalidOrgMembershipRequest.save(); - invalidOrgMembershipRequestId = savedInvalidOrgMembershipRequest._id; - - const savedInvalidUserMembershipRequest = - await invalidUserMembershipRequest.save(); - invalidUserMembershipRequestId = savedInvalidUserMembershipRequest._id; - - const admin = await User.findById(adminId); - admin.overwrite({ - ...admin._doc, - joinedOrganizations: [organizationId], - createdOrganizations: [organizationId], - adminFor: [organizationId], - }); - await admin.save(); - - const member = await User.findById(memberId); - member.overwrite({ - ...member._doc, - joinedOrganizations: [organizationId], - }); - await member.save(); - - const membershipRequester = await User.findById(membershipRequesterId); - membershipRequester.overwrite({ - ...membershipRequester._doc, - membershipRequests: [validMembershipRequestId], - }); - await membershipRequester.save(); - - savedOrg.overwrite({ - ...savedOrg._doc, - membershipRequests: [validMembershipRequestId], - }); - await savedOrg.save(); -}); - -afterAll(async () => { - await User.findByIdAndDelete(adminId); - await User.findByIdAndDelete(membershipRequesterId); - await User.findByIdAndDelete(memberId); - - await Organization.findByIdAndDelete(organizationId); - await MembershipRequest.findByIdAndDelete(validMembershipRequestId); - await MembershipRequest.findByIdAndDelete(invalidOrgMembershipRequestId); - await MembershipRequest.findByIdAndDelete(invalidUserMembershipRequestId); - await MembershipRequest.findByIdAndDelete(alreadyMemberMembershipRequestId); - - await database.disconnect(); -}); - -describe('Cancel membership request', () => { - test('Cancel Membership : Request Not found Check', async () => { - await expect(async () => { - await cancelMembershipRequest( - {}, - { membershipRequestId: new ObjectId() }, - { userId: adminId } - ); - }).rejects.toThrow(MEMBERSHIP_REQUEST_NOT_FOUND); - }); - - test('Cancel Membership : Organization not found Check', async () => { - await expect(async () => { - await cancelMembershipRequest( - {}, - { membershipRequestId: invalidOrgMembershipRequestId }, - { userId: adminId } - ); - }).rejects.toThrow(ORGANIZATION_NOT_FOUND); - }); - test('Cancel Membership : User not found Check', async () => { - await expect(async () => { - await cancelMembershipRequest( - {}, - { membershipRequestId: validMembershipRequestId }, - { userId: new ObjectId() } - ); - }).rejects.toThrow(USER_NOT_FOUND); - }); - - test('Cancel Membership : User not Admin found Check', async () => { - await expect(async () => { - await cancelMembershipRequest( - {}, - { membershipRequestId: validMembershipRequestId }, - { userId: memberId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - test('Cancel Membership : A Membership is canceled sucessfully.', async () => { - let membershipRequest = await cancelMembershipRequest( - {}, - { membershipRequestId: validMembershipRequestId }, - { userId: membershipRequesterId } - ); - const user = User.find(membershipRequesterId); - const savedMembershipRequest = await MembershipRequest.findById( - validMembershipRequestId - ); - expect(savedMembershipRequest).toBeFalsy(); - expect(membershipRequest).toHaveProperty('status', 'ACTIVE'); - expect(user.membershipRequests).toBe(undefined); - }); -}); diff --git a/tests/resolvers/membership_request_mutations/reject_membership_request.spec.js b/tests/resolvers/membership_request_mutations/reject_membership_request.spec.js deleted file mode 100644 index 5b194e5a3a..0000000000 --- a/tests/resolvers/membership_request_mutations/reject_membership_request.spec.js +++ /dev/null @@ -1,188 +0,0 @@ -const shortid = require('shortid'); -const rejectMembershipRequest = require('../../../lib/resolvers/membership_request_mutations/reject_membership_request'); -const { - Types: { ObjectId }, -} = require('mongoose'); - -const database = require('../../../db'); -const getUserIdFromSignUp = require('../../functions/getUserIdFromSignup'); -const Organization = require('../../../lib/models/Organization'); -const User = require('../../../lib/models/User'); -const MembershipRequest = require('../../../lib/models/MembershipRequest'); -const { - MEMBERSHIP_REQUEST_NOT_FOUND, - ORGANIZATION_NOT_FOUND, - USER_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -let adminId; -let memberId; -let membershipRequesterId; - -let organizationId; -let validMembershipRequestId; -let invalidOrgMembershipRequestId; -let invalidUserMembershipRequestId; - -beforeAll(async () => { - // we need 1 org, 1 admin, 1 requester, 1 member - require('dotenv').config(); - await database.connect(); - - const adminEmail = `${shortid.generate().toLowerCase()}@test.com`; - adminId = await getUserIdFromSignUp(adminEmail); - - const memberEmail = `${shortid.generate().toLowerCase()}@test.com`; - memberId = await getUserIdFromSignUp(memberEmail); - - const membershipRequesterEmail = `${shortid - .generate() - .toLowerCase()}@test.com`; - membershipRequesterId = await getUserIdFromSignUp(membershipRequesterEmail); - - const organization = new Organization({ - name: 'an organization', - description: - 'an organization for testing the reject_membership_request resolver', - isPublic: true, - visibileInSearch: true, - status: 'ACTIVE', - members: [adminId, memberId], - admins: [adminId], - posts: [], - membershipRequests: [], - blockedUsers: [], - groupChats: [], - image: '', - creator: adminId, - }); - - const savedOrg = await organization.save(); - organizationId = savedOrg._id; - - const membershipRequest = new MembershipRequest({ - organization: organizationId, - user: membershipRequesterId, - }); - const invalidOrgMembershipRequest = new MembershipRequest({ - organization: new ObjectId(), - user: membershipRequesterId, - }); - const invalidUserMembershipRequest = new MembershipRequest({ - organization: organizationId, - user: new ObjectId(), - }); - - const savedMembershipRequest = await membershipRequest.save(); - validMembershipRequestId = savedMembershipRequest._id; - - const savedInvalidOrgMembershipRequest = - await invalidOrgMembershipRequest.save(); - invalidOrgMembershipRequestId = savedInvalidOrgMembershipRequest._id; - - const savedInvalidUserMembershipRequest = - await invalidUserMembershipRequest.save(); - invalidUserMembershipRequestId = savedInvalidUserMembershipRequest._id; - - const admin = await User.findById(adminId); - admin.overwrite({ - ...admin._doc, - joinedOrganizations: [organizationId], - createdOrganizations: [organizationId], - adminFor: [organizationId], - }); - await admin.save(); - - const member = await User.findById(memberId); - member.overwrite({ - ...member._doc, - joinedOrganizations: [organizationId], - }); - await member.save(); - - const membershipRequester = await User.findById(membershipRequesterId); - membershipRequester.overwrite({ - ...membershipRequester._doc, - membershipRequests: [validMembershipRequestId], - }); - await membershipRequester.save(); - - savedOrg.overwrite({ - ...savedOrg._doc, - membershipRequests: [validMembershipRequestId], - }); - await savedOrg.save(); -}); - -afterAll(async () => { - await User.findByIdAndDelete(adminId); - await User.findByIdAndDelete(membershipRequesterId); - await User.findByIdAndDelete(memberId); - - await Organization.findByIdAndDelete(organizationId); - await MembershipRequest.findByIdAndDelete(validMembershipRequestId); - await MembershipRequest.findByIdAndDelete(invalidOrgMembershipRequestId); - await MembershipRequest.findByIdAndDelete(invalidUserMembershipRequestId); - - await database.disconnect(); -}); - -describe('reject membership request', () => { - test("membership request doesn't exist", async () => { - await expect(async () => { - await rejectMembershipRequest( - {}, - { membershipRequesterId: new ObjectId() }, - { userId: adminId } - ); - }).rejects.toThrow(MEMBERSHIP_REQUEST_NOT_FOUND); - }); - test("organization doesn't exist", async () => { - await expect(async () => { - await rejectMembershipRequest( - {}, - { membershipRequestId: invalidOrgMembershipRequestId }, - { userId: adminId } - ); - }).rejects.toThrow(ORGANIZATION_NOT_FOUND); - }); - - test("user doesn't exist", async () => { - await expect(async () => { - await rejectMembershipRequest( - {}, - { membershipRequestId: invalidUserMembershipRequestId }, - { userId: adminId } - ); - }).rejects.toThrow(USER_NOT_FOUND); - }); - - test('user is not the admin of the org', async () => { - await expect(async () => { - await rejectMembershipRequest( - {}, - { membershipRequestId: validMembershipRequestId }, - { userId: memberId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - - test('a valid accept member', async () => { - const membershipRequest = await rejectMembershipRequest( - {}, - { membershipRequestId: validMembershipRequestId }, - { userId: adminId } - ); - const savedMembershipRequest = await MembershipRequest.findOne( - validMembershipRequestId - ); - const org = await Organization.findById(organizationId); - const user = await User.findById(membershipRequesterId); - - expect(membershipRequest._id).toEqual(validMembershipRequestId); - expect(savedMembershipRequest).toBeFalsy(); - expect(org.membershipRequests.length).toBeFalsy(); - expect(user.membershipRequests.length).toBeFalsy(); - }); -}); diff --git a/tests/resolvers/mutation.spec.js b/tests/resolvers/mutation.spec.js deleted file mode 100644 index 5a3f6ec0e8..0000000000 --- a/tests/resolvers/mutation.spec.js +++ /dev/null @@ -1,76 +0,0 @@ -const Mutation = require('../../lib/resolvers/Mutation'); -describe('Test for Mutation', () => { - test('Mutation should have necessary properties', () => { - expect(Mutation).toHaveProperty('signUp'); - expect(Mutation).toHaveProperty('login'); - expect(Mutation).toHaveProperty('saveFcmToken'); - expect(Mutation).toHaveProperty('logout'); - expect(Mutation).toHaveProperty('refreshToken'); - expect(Mutation).toHaveProperty('revokeRefreshTokenForUser'); - expect(Mutation).toHaveProperty('updateLanguage'); - - expect(Mutation).toHaveProperty('updateUserProfile'); - expect(Mutation).toHaveProperty('createOrganization'); - - expect(Mutation).toHaveProperty('createEvent'); - expect(Mutation).toHaveProperty('registerForEvent'); - expect(Mutation).toHaveProperty('removeEvent'); - expect(Mutation).toHaveProperty('removeEvent'); - expect(Mutation).toHaveProperty('unregisterForEventByUser'); - - expect(Mutation).toHaveProperty('createAdmin'); - expect(Mutation).toHaveProperty('removeAdmin'); - expect(Mutation).toHaveProperty('updateOrganization'); - expect(Mutation).toHaveProperty('removeOrganization'); - expect(Mutation).toHaveProperty('joinPublicOrganization'); - expect(Mutation).toHaveProperty('leaveOrganization'); - expect(Mutation).toHaveProperty('removeMember'); - - expect(Mutation).toHaveProperty('adminRemovePost'); - expect(Mutation).toHaveProperty('adminRemoveGroup'); - expect(Mutation).toHaveProperty('adminRemoveEvent'); - - expect(Mutation).toHaveProperty('createPost'); - expect(Mutation).toHaveProperty('removePost'); - expect(Mutation).toHaveProperty('likePost'); - expect(Mutation).toHaveProperty('unlikePost'); - expect(Mutation).toHaveProperty('createTask'); - expect(Mutation).toHaveProperty('removeTask'); - expect(Mutation).toHaveProperty('updateTask'); - expect(Mutation).toHaveProperty('sendMembershipRequest'); - expect(Mutation).toHaveProperty('acceptMembershipRequest'); - expect(Mutation).toHaveProperty('rejectMembershipRequest'); - expect(Mutation).toHaveProperty('cancelMembershipRequest'); - - expect(Mutation).toHaveProperty('blockUser'); - expect(Mutation).toHaveProperty('unblockUser'); - - expect(Mutation).toHaveProperty('createComment'); - expect(Mutation).toHaveProperty('removeComment'); - expect(Mutation).toHaveProperty('likeComment'); - expect(Mutation).toHaveProperty('unlikeComment'); - - expect(Mutation).toHaveProperty('addUserImage'); - expect(Mutation).toHaveProperty('removeUserImage'); - expect(Mutation).toHaveProperty('addOrganizationImage'); - expect(Mutation).toHaveProperty('removeOrganizationImage'); - - expect(Mutation).toHaveProperty('removeOrganizationImage'); - expect(Mutation).toHaveProperty('removeDirectChat'); - expect(Mutation).toHaveProperty('sendMessageToDirectChat'); - - expect(Mutation).toHaveProperty('createGroupChat'); - expect(Mutation).toHaveProperty('removeGroupChat'); - expect(Mutation).toHaveProperty('sendMessageToGroupChat'); - expect(Mutation).toHaveProperty('addUserToGroupChat'); - expect(Mutation).toHaveProperty('removeUserFromGroupChat'); - expect(Mutation).toHaveProperty('blockPluginCreationBySuperadmin'); - - expect(Mutation).toHaveProperty('createMessageChat'); - expect(Mutation).toHaveProperty('addLanguageTranslation'); - - expect(Mutation).toHaveProperty('createPlugin'); - expect(Mutation).toHaveProperty('updatePluginStatus'); - expect(Mutation).toHaveProperty('updatePluginInstalledOrgs'); - }); -}); diff --git a/tests/resolvers/organization_mutations/removeOrganization.spec.js b/tests/resolvers/organization_mutations/removeOrganization.spec.js deleted file mode 100644 index 5e221109fc..0000000000 --- a/tests/resolvers/organization_mutations/removeOrganization.spec.js +++ /dev/null @@ -1,229 +0,0 @@ -const shortid = require('shortid'); -const removeOrganization = require('../../../lib/resolvers/organization_mutations/removeOrganization'); -const mongoose = require('mongoose'); - -const database = require('../../../db'); -const getUserIdFromSignUp = require('../../functions/getUserIdFromSignup'); -const Organization = require('../../../lib/models/Organization'); -const Post = require('../../../lib/models/Post'); -const Comment = require('../../../lib/models/Comment'); -const User = require('../../../lib/models/User'); -const MembershipRequest = require('../../../lib/models/MembershipRequest'); - -const { - USER_NOT_FOUND, - ORGANIZATION_NOT_FOUND, - USER_NOT_AUTHORIZED, -} = require('../../../constants'); - -let adminId; -let memberId; -let membershipRequesterId; -let blockedId; - -let organizationId; -let membershipRequestId; -let postId; -let commentId; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - - const adminEmail = `${shortid.generate().toLowerCase()}@test.com`; - adminId = await getUserIdFromSignUp(adminEmail); - - const memberEmail = `${shortid.generate().toLowerCase()}@test.com`; - memberId = await getUserIdFromSignUp(memberEmail); - - const membershipRequesterEmail = `${shortid - .generate() - .toLowerCase()}@test.com`; - membershipRequesterId = await getUserIdFromSignUp(membershipRequesterEmail); - - const blockedEmail = `${shortid.generate().toLowerCase()}@test.com`; - blockedId = await getUserIdFromSignUp(blockedEmail); - - const organization = new Organization({ - name: 'an organization', - description: 'an organization for testing the removeOrganization resolver', - isPublic: true, - visibileInSearch: true, - status: 'ACTIVE', - members: [adminId, memberId], - admins: [adminId], - posts: [], - membershipRequests: [], - blockedUsers: [blockedId], - groupChats: [], - image: '', - creator: adminId, - }); - - const savedOrg = await organization.save(); - organizationId = savedOrg._id; - - const membershipRequest = new MembershipRequest({ - organization: organizationId, - user: membershipRequesterId, - }); - - const savedMembershipRequest = await membershipRequest.save(); - membershipRequestId = savedMembershipRequest._id; - - // adding posts - const post = new Post({ - status: 'ACTIVE', - likedBy: [adminId, memberId], - likeCount: 2, - comments: [], - text: 'a', - title: 'a', - imageUrl: 'a.png', - videoUrl: 'a', - creator: memberId, - organization: organizationId, - }); - - const savedPost = await post.save(); - postId = savedPost._id; - - const comment = new Comment({ - likedBy: [adminId, memberId], - likeCount: 0, - status: 'ACTIVE', - text: 'comment', - creator: memberId, - post: postId, - }); - - const savedComment = await comment.save(); - commentId = savedComment._id; - savedPost.overwrite({ - ...savedPost._doc, - comments: [commentId], - commentCount: 1, - }); - - const admin = await User.findById(adminId); - admin.overwrite({ - ...admin._doc, - joinedOrganizations: [organizationId], - createdOrganizations: [organizationId], - adminFor: [organizationId], - }); - await admin.save(); - - const member = await User.findById(memberId); - member.overwrite({ - ...member._doc, - joinedOrganizations: [organizationId], - }); - await member.save(); - - const membershipRequester = await User.findById(membershipRequesterId); - membershipRequester.overwrite({ - ...membershipRequester._doc, - membershipRequests: [membershipRequestId], - }); - await membershipRequester.save(); - - const blocked = await User.findById(blockedId); - blocked.overwrite({ - ...blocked._doc, - organizationsBlockedBy: [organizationId], - }); - await blocked.save(); - await savedOrg.overwrite({ - ...savedOrg._doc, - membershipRequests: [membershipRequestId], - posts: postId, - }); - await savedPost.save(); - await savedOrg.save(); -}); - -afterAll(async () => { - await User.findByIdAndDelete(adminId); - await User.findByIdAndDelete(membershipRequesterId); - await User.findByIdAndDelete(blockedId); - await User.findByIdAndDelete(memberId); - - await Organization.findByIdAndDelete(organizationId); - await MembershipRequest.findByIdAndDelete(membershipRequestId); - - await Post.findByIdAndDelete(postId); - await Comment.findByIdAndDelete(commentId); - - await database.disconnect(); -}); - -describe('testing removeOrganization resolver', () => { - test("user doesn't exist", async () => { - await expect(async () => { - await removeOrganization({}, {}, { userId: mongoose.Types.ObjectId() }); - }).rejects.toThrow(USER_NOT_FOUND); - }); - - test("organization doesn't exist", async () => { - await expect(async () => { - await removeOrganization( - {}, - { id: mongoose.Types.ObjectId() }, - { userId: memberId } - ); - }).rejects.toThrow(ORGANIZATION_NOT_FOUND); - }); - - test('user is not the creator of org', async () => { - await expect(async () => { - await removeOrganization( - {}, - { id: organizationId }, - { userId: memberId } - ); - }).rejects.toThrow(USER_NOT_AUTHORIZED); - }); - - test("organization doesn't exist after deletion", async () => { - try { - await removeOrganization({}, { id: organizationId }, { userId: adminId }); - const organization = await Organization.findById(organizationId); - expect(organization).toBe(null); - } catch (err) { - console.log('this is an error: ', err); - } - }); - test("posts for an organization are removed after it's been removed", async () => { - const post = await Post.findById(postId); - expect(post).toBe(null); - }); - test("comments for an organization are removed after it's been removed", async () => { - const comment = await Comment.findById(commentId); - expect(comment).toBe(null); - }); - - test("members can't see organization after it's been removed", async () => { - const member = await User.findById(memberId); - expect(member.joinedOrganizations).toHaveLength(0); - }); - - test("admins and creator can't see organization after it's been removed", async () => { - const admin = await User.findById(adminId); - expect(admin.adminFor).toHaveLength(0); - expect(admin.createdOrganizations).toHaveLength(0); - }); - - test("blocked users aren't blocked from an organization after it's been removed", async () => { - const blocked = await User.findById(blockedId); - expect(blocked.organizationsBlockedBy).toHaveLength(0); - }); - test('membership requests are removed afted an organization deletion', async () => { - const membershipRequester = await User.findById(membershipRequesterId); - const membershipRequest = await MembershipRequest.findById( - membershipRequestId - ); - expect(membershipRequest).toBe(null); - expect(membershipRequester.membershipRequests).toHaveLength(0); - }); -}); diff --git a/tests/resolvers/organization_mutations/updateOrganization.spec.js b/tests/resolvers/organization_mutations/updateOrganization.spec.js deleted file mode 100644 index d22389b535..0000000000 --- a/tests/resolvers/organization_mutations/updateOrganization.spec.js +++ /dev/null @@ -1,174 +0,0 @@ -const axios = require('axios'); -const { URL, ORGANIZATION_NOT_FOUND } = require('../../../constants'); -const getToken = require('../../functions/getToken'); -const shortid = require('shortid'); -const updateOrganization = require('../../../lib/resolvers/organization_mutations/updateOrganization'); -const database = require('../../../db'); -const mongoose = require('mongoose'); - -let token; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - require('dotenv').config(); // pull env variables from .env file - await database.connect(); // connect the database before running any test in this file's scope -}); - -afterAll(() => { - database.disconnect(); // disconnect the database after running every test in this file's scope -}); - -describe('organization resolvers', () => { - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - var createdOrgId; - - // test for creating organization - test('createOrganization', async () => { - const createdOrgResponse = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - apiUrl : "test url" - }) { - _id, - name, - description, - creator{ - email - }, - admins{ - email - }, - members{ - email - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = createdOrgResponse; - createdOrgId = createdOrgResponse.data.data.createOrganization._id; - expect(data.data.createOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - description: expect.any(String), - creator: expect.objectContaining({ - email: expect.any(String), - }), - admins: expect.any(Array), - members: expect.any(Array), - }) - ); - }); - - // test for if no organization found, throw an error - test('if no organization is found for the provided args.id, throws NotFoundError', async () => { - // Random id to pass as chat id - const args = { id: mongoose.Types.ObjectId() }; - const context = { - userId: mongoose.Types.ObjectId(), - }; - await expect(async () => { - await updateOrganization({}, args, context); - }).rejects.toEqual(Error(ORGANIZATION_NOT_FOUND)); - }); - - // test for update organization - test('updateOrganization', async () => { - const updateOrgRes = await axios.post( - URL, - { - query: ` - mutation { - updateOrganization( - id: "${createdOrgId}" - data: { - name: "test2 org" - description: "new description" - isPublic: ${!isPublic_boolean} - visibleInSearch: ${!visibleInSearch_boolean} - } - ) { - _id - name - description - isPublic - visibleInSearch - apiUrl - image - creator { - _id - firstName - } - members { - _id - firstName - } - admins { - _id - firstName - } - membershipRequests { - _id - organization{ - _id - name - description - } - user { - _id - firstName - } - } - blockedUsers { - _id - firstName - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const args = { - id: createdOrgId, - data: { - name: 'test2 org', - description: 'new description', - isPublic: `${!isPublic_boolean}`, - visibleInSearch: `${!visibleInSearch_boolean}`, - }, - }; - const userId = updateOrgRes.data.data.updateOrganization.admins[0]._id; - const context = { - userId: userId, - }; - const response = await updateOrganization({}, args, context); // passing parameters to original function - - expect(response).toEqual( - expect.objectContaining({ - name: 'test2 org', - description: 'new description', - }) - ); - }); -}); diff --git a/tests/resolvers/organization_query/organizations.spec.js b/tests/resolvers/organization_query/organizations.spec.js deleted file mode 100644 index dd50530e77..0000000000 --- a/tests/resolvers/organization_query/organizations.spec.js +++ /dev/null @@ -1,256 +0,0 @@ -//---------------------**************************************-------------------------------------- -//THE PURPOSE OF THIS FILE IS TO CHECK THE TEST CODE FOR @[organizations] API -//IN ORDER TO GET THE COVERAGE OF 100% WE NEED TO MAKE SURE THAT ALL THE -//POSSIBLE CASES ARE CONSIDERED WHILE WRITING TEST CODE COVERING EVERY LINE OF CODE in @[organizations] API FUNCTION -// -//PLEASE NOTE THAT COVERAGE OF 100% WILL ONLY BE GENERATED IF EACH LINE OF MAIN FUNCTION IS RUN BY TEST CODE -// -//---------------------**************************************-------------------------------------- - -// IMPORTING THE API THAT NEEDS TO BE TESTED FROM THE DESIRE RESOLVER FUNCTION -const organizationQuery = require('../../../lib/resolvers/organization_query/organizations'); -// IMPORTING THE ORGANOSATION CREATION API THAT WILL BE NEEDED WHILE COVERING ALL CASES IN TEST CODE -const organizationMutation = require('../../../lib/resolvers/organization_mutations/createOrganization'); - -// SINCE OUR API WILL CALL ON DATABASE, WE NEED TO MAKE SURE THE DATABASE IS CONNECTED -// THE db.js FILE PRESENT IN THE ROOT WILL DO OUR WORK, SO WE NEED TO IMPORT THAT FILE -const database = require('../../../db'); - -// THE shortid IS UTILISED TO GET UNIQUE IDENTIFIER WHICH IS USED AS A RANDOM SET -// OF NUMBERS IN ORDER TO PERFORM THE SIGNUP -//THE SIGNUP IS REQUIRED IN ORDER TO HAVE ACCESS TO CREATE ORGANISATION AND VIEW ORGANISATION -//BOTH OF THIS WILL BE DONE WHEN WE WILL COVERING TEST CASE SCENARIOS -const shortid = require('shortid'); - -// THE FUNCTION PURPOSE IS TO SIGNUP A USER AND GET THE ITS UNIQUE ID -// AS IT WILL BE UTILISED WHILE CALLING THE FUNCTION QUERY -const getUserId = require('../../functions/getUserIdFromSignup'); - -// THE GLOBAL VARIABLE WHICH WILL STORE THE USER ID AFTER THE SIGNUP -let userId; - -// BEFORE TESTING OUR QUERY WE NEED TO MAKE SURE OF THE FOLLOWING REQUIREMENTS -// 1. OUR DATABASE IS UP AND RUNNING -// 2. OUR USER IS SIGNED UP OR LOGGED IN -// -// IN ORDER TO MAKE SURE OUR DATABASE IS RUNNING, OUR ENVIRONMENT VARIABLES -// NEEDS TO BE CONFIGURED -// -// BELOW FUNCTION MAKE SURE ALL THE ABOVE WORKS ARE DONE -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); - - const args = { - data: { - name: 'Palisadoes Foundation Members', - description: 'For all contributors of Palisadoes', - location: 'Earth', - isPublic: true, - visibleInSearch: true, - }, - }; - - await organizationMutation({}, args, { - userId: userId, - }); -}); - -//AFTER WE ARE DONE WITH OUR TESTING WE NEED TO CLOSE DOWN THE DATABASE TO AVOID -//RUNNING MULTIPLE CONNECTION ON THE SAME DATABASE SERVER WHICH WILL INCREASE ITS LOAD -afterAll(() => { - database.disconnect(); -}); - -//THE PURPOSE OF THE FUNCTION IS TO RETURN RESULTS PROVIDED AND ACCEPTED -//IF ORDERY INPUT PARAMETER IS PROVIDED BY THE USER -// -//SINCE WE HAVE 8 ORDERBY PARAMETERS ARE POSSIBLE WE NEED TO CHECK -//EVERY SINGLE ONE IN ORDER TO GET COVERAGE TO 100% -const checkOrderByInput = async (val) => { - const getRandomOrderByVal = val; - const apiArgs = { - orderBy: getRandomOrderByVal, - }; - - let apiResponse = await organizationQuery({}, apiArgs, { - userId: userId, - }); - - let apiResponseStructuredFormatArray = Array.from( - Array(apiResponse.length > 5 ? 5 : apiResponse.length).keys() - ); - - if (apiResponseStructuredFormatArray.length === 5) { - apiResponse = apiResponse.slice(0, 5); - } - - let index = 0; - apiResponse.forEach((element) => { - const result = { - id: element['_id'], - name: element['name'], - description: element['description'], - apiUrl: element['apiUrl'], - }; - - apiResponseStructuredFormatArray[index] = result; - index++; - }); - - const orderByfilterArray = getRandomOrderByVal.split('_'); - const orderByInputName = orderByfilterArray[0]; - const orderByOrder = orderByfilterArray[1]; - - let outputResult = Array.from( - Array(apiResponseStructuredFormatArray.length).keys() - ); - - index = 0; - apiResponseStructuredFormatArray.forEach((element) => { - outputResult[index] = element[orderByInputName]; - index++; - }); - - //SORTING IS PERFORMED IN RESPONSE TO CHECK IF ANY CHANGES HAPPENED - //IF INCASE IT DID THE TEST WILL FAIL SUGGESTING THAT orderBy PARAMETER IS NOT WORKING - outputResult = outputResult.sort((a, b) => { - if (orderByOrder === 'ASC') { - // eslint-disable-next-line prettier/prettier - return a[orderByInputName] > b[orderByInputName] ? 1 : b[orderByInputName] > a[orderByInputName] ? -1 : 0; - } - - // eslint-disable-next-line prettier/prettier - return a[orderByInputName] < b[orderByInputName] ? 1 : b[orderByInputName] < a[orderByInputName] ? -1 : 0; - }); - - let responseStructredResultExpectation = Array.from( - Array(apiResponseStructuredFormatArray.length).keys() - ); - - index = 0; - apiResponseStructuredFormatArray.forEach((element) => { - responseStructredResultExpectation[index] = element[orderByInputName]; - index++; - }); - - return { - outputResult: outputResult, - responseStructredResultExpectation: responseStructredResultExpectation, - }; -}; - -// OUR TEST NEEDS TO BE BREAKDOWN INTO SEVERAL SMALLER CASES AND THEY -// NEEDS TO BE GROUP UNDER ONE -// -// DESCRIBE FORMS THE GROUP UNDER WHICH ALL SCENRAIO WILL BE TESTED FOR A GIVEN API -describe('Organization Query', () => { - // THIS IS THE FIRST TEST CASE WHERE NO PARAMETERS IS PROVIDED BY THE USER - // IN THE CASE ARRAY OF ORGANIZATIONS IS EXPECTED AS RESULTS - // - // IT COVERS THE FOLLOWING MAIN LINE NO: - // 11,12,35,39,57 - test('Without any input arguments by user', async () => { - const response = await organizationQuery( - {}, - {}, - { - userId: userId, - } - ); - - expect(response).toEqual(expect.any(Array)); - }); - - // THIS IS THE CASE WHEN USER PROVIDES ORDERBY INPUT IN API - //IF WE LOOK CAREFULLY THIS COVERS THE MAIN PART OF OUR API FILE AND TEST MAJOR LINES - // - // IT COVERS THE FOLLOWING MAIN LINE NO: - // 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 - test('orderBy input arguments provided by user', async () => { - const orderByVal = [ - 'id_ASC', - 'id_DESC', - 'name_ASC', - 'name_DESC', - 'description_ASC', - 'description_DESC', - 'apiUrl_ASC', - 'apiUrl_DESC', - ]; - - // THE ARRAY IS RESPONSIBLE FOR CHECKING WHEATHER THE RESUTS ARE SORTED - const outputResultArray = Array.from(Array(orderByVal.length).keys()); - // THE ARRAY OF RESPONSE - const expectedResultArray = Array.from(Array(orderByVal.length).keys()); - - //THE LOOP TAKES ALL THE ORDER BY CASES AND STORES THE RESULTS IN ARRAY - for (let i = 0; i < orderByVal.length; i++) { - const result = await checkOrderByInput(orderByVal[i]); - outputResultArray[i] = result['outputResult']; - expectedResultArray[i] = result['responseStructredResultExpectation']; - } - - //FOR ALL THE CASES BOTH EXPECTED AND ACTUAL VALUES ARE CHECKED - expect(expectedResultArray).toBeTruthy(); - }); - - //THIS IS THE CASE WHERE USER PROVIDES THE ORGANISATION ID - //TO GET THE RESPONSE OF ONE SINGLE ORGANISATION - // - // IT COVERS THE FOLLOWING MAIN LINE NO: - // 41,42,43,44,55 - test('Organisation Id provided by user', async () => { - const args = { - data: { - name: 'Palisadoes Foundation Members', - description: 'For all contributors of Palisadoes', - location: 'Earth', - isPublic: true, - visibleInSearch: true, - }, - }; - const newOrganization = await organizationMutation({}, args, { - userId: userId, - }); - - const queryResponse = await organizationQuery( - {}, - { - id: newOrganization['_id'], - }, - { - userId: userId, - } - ); - - expect(queryResponse).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - _id: newOrganization['_id'], - }), - ]) - ); - }); - - //THIS IS THE CASE WHERE USER PROVIDES THE WRONG ORGANISATION ID - //IN THIS CASE TEST CODE CHECKS IF ERROR IS THROWN OR NOT - // - // IT COVERS THE FOLLOWING MAIN LINE NO: - // 46,47,48,49,50,51,52,53 - test("Organisation Id provided by user doesn't exist", async () => { - await expect(async () => { - await organizationQuery( - {}, - { - id: '60528166cc96e8d1bf2ace99', - }, - { - userId: userId, - } - ); - }).rejects.toEqual(Error('Organization not found')); - }); -}); diff --git a/tests/resolvers/plugin_mutations/updatePluginInstallStatus.spec.js b/tests/resolvers/plugin_mutations/updatePluginInstallStatus.spec.js deleted file mode 100644 index 24c4baf5fa..0000000000 --- a/tests/resolvers/plugin_mutations/updatePluginInstallStatus.spec.js +++ /dev/null @@ -1,22 +0,0 @@ -const database = require('../../../db'); -require('../../../lib/models/Plugin'); -const updatePluginInstalledOrgs = require('../../../lib/resolvers/plugin_mutations/updatePluginStatus'); -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing updatePluginInstalledOrgs', () => { - test('Find existing post by post id', async () => { - const response = await updatePluginInstalledOrgs( - {}, - { id: '62cfcd6233bbe266f59644db', installedOrgs: [] }, - {} - ); - expect(response).toBeFalsy(); // result is null in github actions - }); -}); diff --git a/tests/resolvers/plugin_mutations/updatePluginInstalledOrgs.spec.js b/tests/resolvers/plugin_mutations/updatePluginInstalledOrgs.spec.js deleted file mode 100644 index 320797d745..0000000000 --- a/tests/resolvers/plugin_mutations/updatePluginInstalledOrgs.spec.js +++ /dev/null @@ -1,22 +0,0 @@ -const database = require('../../../db'); -require('../../../lib/models/Plugin'); -const updatePluginInstalledOrgs = require('../../../lib/resolvers/plugin_mutations/updatePluginInstalledOrgs'); -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing updatePluginInstalledOrgs', () => { - test('Find existing post by post id', async () => { - const response = await updatePluginInstalledOrgs( - {}, - { id: '62cfcd6233bbe266f59644db', installedOrgs: [] }, - {} - ); - expect(response).toBeFalsy(); // response is null - }); -}); diff --git a/tests/resolvers/plugin_query/getPlugins.spec.js b/tests/resolvers/plugin_query/getPlugins.spec.js deleted file mode 100644 index a804878cce..0000000000 --- a/tests/resolvers/plugin_query/getPlugins.spec.js +++ /dev/null @@ -1,18 +0,0 @@ -const database = require('../../../db'); -require('../../../lib/models/Plugin'); -const getPlugins = require('../../../lib/resolvers/plugin_query/getPlugins'); -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Post query testing for post resolver', () => { - test('Testing getPlugins Functions', async () => { - const response = await getPlugins(); - expect(response).toBeTruthy(); - }); -}); diff --git a/tests/resolvers/post_query/commentsByPost.spec.js b/tests/resolvers/post_query/commentsByPost.spec.js deleted file mode 100644 index 7cdb395125..0000000000 --- a/tests/resolvers/post_query/commentsByPost.spec.js +++ /dev/null @@ -1,162 +0,0 @@ -const database = require('../../../db'); -const shortid = require('shortid'); -const User = require('../../../lib/models/User'); -const Organization = require('../../../lib/models/Organization'); -const Post = require('../../../lib/models/Post'); -const Comment = require('../../../lib/models/Comment'); -const commentsByPost = require('../../../lib/resolvers/post_query/commentsByPost'); - -const { - COMMENT_NOT_FOUND, - POST_NOT_FOUND, - USER_NOT_FOUND, - ORGANIZATION_NOT_FOUND, -} = require('../../../constants'); - -let user; -let org; -let post; -let comment; - -const createUser = async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - let newUser = await User.create({ - firstName: shortid.generate().toLowerCase(), - lastName: shortid.generate().toLowerCase(), - email: generatedEmail, - userType: 'USER', - password: 'password', - }); - return newUser; -}; - -const createOrganization = async () => { - let newOrg = await Organization.create({ - name: 'abcd org', - description: shortid.generate().toLowerCase(), - isPublic: true, - location: 'location', - creator: user._id, - admins: [user._id], - members: [user._id], - }); - return newOrg; -}; - -const createPost = async () => { - let newPost = await Post.create({ - text: 'text', - title: 'title', - creator: user._id, - organization: org._id, - }); - return newPost; -}; - -const createComment = async () => { - let newComment = await Comment.create({ - text: 'new comment', - creator: user._id, - post: post._id, - likedBy: [user._id], - likeCount: 1, - }); - return newComment; -}; - -const deleteUser = async (id) => { - await User.deleteOne({ _id: id }); -}; - -const deleteOrganization = async (id) => { - await Organization.deleteOne({ _id: id }); -}; - -const deletePost = async (id) => { - await Post.deleteOne({ _id: id }); -}; - -const deleteComment = async (id) => { - await Comment.deleteOne({ _id: id }); -}; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - user = await createUser(); - if (user) { - org = await createOrganization(); - if (org) { - post = await createPost(); - if (post) { - comment = await createComment(); - } - } - } else { - throw new Error('User is required to create a organization'); - } -}); - -afterAll(async () => { - await deleteComment(comment._id); - await deletePost(post._id); - await deleteOrganization(org._id); - await deleteUser(user._id); - database.disconnect(); -}); - -describe('Comment query for commentsByPost resolver', () => { - test('Find existing comment by comment id', async () => { - const arg = { - id: `${comment.post._id}`, - }; - const response = await commentsByPost({}, arg); - expect(response).toMatchObject([{ text: 'new comment' }]); - }); - test('Comment does not exist by comment id', async () => { - const arg = { - id: '624300b406807d0e7453ebca', - }; - await expect(async () => { - await commentsByPost({}, arg); - }).rejects.toThrow(COMMENT_NOT_FOUND); - }); - test('User does not exist', async () => { - deleteUser(user._id); - const arg = { - id: `${comment.post._id}`, - }; - await expect(async () => { - await commentsByPost({}, arg); - }).rejects.toThrow(USER_NOT_FOUND); - }); - test('Organization does not exist', async () => { - await deleteComment(comment._id); - await deletePost(post._id); - await deleteOrganization(org._id); - user = await createUser(); - post = await createPost(); - comment = await createComment(); - const arg = { - id: `${comment.post._id}`, - }; - await expect(async () => { - await commentsByPost({}, arg); - }).rejects.toThrow(ORGANIZATION_NOT_FOUND); - }); - test('Post does not exist', async () => { - await deleteComment(comment._id); - await deletePost(post._id); - await deleteOrganization(org._id); - await deleteUser(user._id); - user = await createUser(); - comment = await createComment(); - org = await createOrganization(); - const arg = { - id: `${comment.post._id}`, - }; - await expect(async () => { - await commentsByPost({}, arg); - }).rejects.toThrow(POST_NOT_FOUND); - }); -}); diff --git a/tests/resolvers/post_query/post.spec.js b/tests/resolvers/post_query/post.spec.js deleted file mode 100644 index 16ee985b35..0000000000 --- a/tests/resolvers/post_query/post.spec.js +++ /dev/null @@ -1,73 +0,0 @@ -const database = require('../../../db'); -const shortid = require('shortid'); -const User = require('../../../lib/models/User'); -const Organization = require('../../../lib/models/Organization'); -const Post = require('../../../lib/models/Post'); -require('../../../lib/models/Comment'); -const getPostByItId = require('../../../lib/resolvers/post_query/post'); -let user; -let org; -let post; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - user = await User.create({ - firstName: shortid.generate().toLowerCase(), - lastName: shortid.generate().toLowerCase(), - email: generatedEmail, - userType: 'USER', - password: 'password', - }); - if (user) { - org = await Organization.create({ - name: 'abcd org', - description: shortid.generate().toLowerCase(), - isPublic: true, - location: 'location', - creator: user._id, - admins: [user._id], - members: [user._id], - }); - if (org) { - post = await Post.create({ - text: 'text', - title: 'title', - creator: user._id, - organization: org._id, - }); - } - } else { - throw new Error('User is required to create a organization'); - } -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Post query testing for post resolver', () => { - test('Find existing post by post id', async () => { - const arg = { - id: `${post._id}`, - }; - const response = await getPostByItId({}, arg); - expect(response).toEqual( - expect.objectContaining({ - text: 'text', - title: 'title', - likeCount: 0, - commentCount: 0, - }) - ); - }); - test('Post not exit with this id', async () => { - const arg = { - id: '6230d726edaf510ca0ba2b9f', - }; - await expect(async () => { - await getPostByItId({}, arg); - }).rejects.toThrow('Post not found'); - }); -}); diff --git a/tests/resolvers/post_query/postsByOrganization.spec.js b/tests/resolvers/post_query/postsByOrganization.spec.js deleted file mode 100644 index acdd68f529..0000000000 --- a/tests/resolvers/post_query/postsByOrganization.spec.js +++ /dev/null @@ -1,585 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../../../constants'); -const getToken = require('../../functions/getToken'); -const shortid = require('shortid'); - -const database = require('../../../db'); -const getUserId = require('../../functions/getUserId'); -const Organization = require('../../../lib/models/Organization'); -const Post = require('../../../lib/models/Post'); -const Comment = require('../../../lib/models/Comment'); -const User = require('../../../lib/models/User'); - -let mainUserId; -let secondUserId; -let thirdUserId; - -let mainOrganization; - -let firstPost; -let secondPost; -let thirdPost; - -beforeAll(async () => { - // Initializing a seed data to test on by - // creating 3 emails one that holds the main organization - // the 2 emails just to like and comment on the testing posts - // then creating 3 posts that can be sorted - // according to the available criterias. - - try { - require('dotenv').config(); - await database.connect(); - - const mainEmail = `${shortid.generate().toLowerCase()}@test.com`; - await getToken(mainEmail); - mainUserId = await getUserId(mainEmail); - - const secondEmail = `${shortid.generate().toLowerCase()}@test.com`; - await getToken(secondEmail); - secondUserId = await getUserId(secondEmail); - - const thirdEmail = `${shortid.generate().toLowerCase()}@test.com`; - await getToken(thirdEmail); - thirdUserId = await getUserId(thirdEmail); - - // adding an organization - const organization = new Organization({ - name: 'mainOrganization', - description: - 'mainOrganization for testing the postsByOrganization resolver', - isPublic: true, - visibileInSearch: true, - status: 'ACTIVE', - members: [mainUserId], - admins: [mainUserId], - groupChats: [], - posts: [], - membershipRequests: [], - blockedUsers: [], - image: '', - creator: mainUserId, - }); - mainOrganization = await organization.save(); - - // adding posts - const createFirstPost = new Post({ - status: 'ACTIVE', - likedBy: [mainUserId], - likeCount: 1, - comments: [], - text: 'a', - title: 'a', - imageUrl: 'a.png', - videoUrl: 'a', - creator: mainUserId, - organization: mainOrganization._id, - }); - firstPost = await createFirstPost.save(); - const createSecondPost = new Post({ - status: 'ACTIVE', - likedBy: [mainUserId, secondUserId], - likeCount: 2, - comments: [], - text: 'b', - title: 'b', - imageUrl: 'b.png', - videoUrl: 'b', - creator: mainUserId, - organization: mainOrganization._id, - }); - secondPost = await createSecondPost.save(); - const createThirdPost = new Post({ - status: 'ACTIVE', - likedBy: [mainUserId, secondUserId, thirdUserId], - likeCount: 3, - comments: [], - text: 'c', - title: 'c', - imageUrl: 'c.png', - videoUrl: 'c', - creator: mainUserId, - organization: mainOrganization._id, - }); - thirdPost = await createThirdPost.save(); - - // adding one comment for the first post, 2 for the second post and 3 for the third post - //first post - const createFirstPostComment1 = new Comment({ - likedBy: [], - likeCount: 0, - status: 'ACTIVE', - text: 'first post comment 1', - creator: mainUserId, - post: firstPost._id, - }); - const firstPostComment1 = await createFirstPostComment1.save(); - firstPost.comments = [firstPostComment1._id]; - firstPost.commentCount = 1; - firstPost = await firstPost.save(); - //second post - const createSecondPostComment1 = new Comment({ - likedBy: [], - likeCount: 0, - status: 'ACTIVE', - text: 'second post comment 1', - creator: mainUserId, - post: secondPost._id, - }); - const createSecondPostComment2 = new Comment({ - likedBy: [], - likeCount: 0, - status: 'ACTIVE', - text: 'second post comment 2', - creator: secondUserId, - post: secondPost._id, - }); - const secondPostComment1 = await createSecondPostComment1.save(); - const secondPostComment2 = await createSecondPostComment2.save(); - secondPost.comments = [secondPostComment1._id, secondPostComment2._id]; - secondPost.commentCount = 2; - secondPost = await secondPost.save(); - //third post - const createThirdPostComment1 = new Comment({ - likedBy: [], - likeCount: 0, - status: 'ACTIVE', - text: 'third post comment 1', - creator: mainUserId, - post: thirdPost._id, - }); - const createThirdPostComment2 = new Comment({ - likedBy: [], - likeCount: 0, - status: 'ACTIVE', - text: 'third post comment 2', - creator: secondUserId, - post: thirdPost._id, - }); - const createThirdPostComment3 = new Comment({ - likedBy: [], - likeCount: 0, - status: 'ACTIVE', - text: 'third post comment 3', - creator: thirdUserId, - post: thirdPost._id, - }); - const thirdPostComment1 = await createThirdPostComment1.save(); - const thirdPostComment2 = await createThirdPostComment2.save(); - const thirdPostComment3 = await createThirdPostComment3.save(); - thirdPost.comments = [ - thirdPostComment1._id, - thirdPostComment2._id, - thirdPostComment3._id, - ]; - thirdPost.commentCount = 3; - thirdPost = await thirdPost.save(); - - firstPost = { ...firstPost._doc }; - secondPost = { ...secondPost._doc }; - thirdPost = { ...thirdPost._doc }; - - firstPost._id = firstPost._id.toString(); - secondPost._id = secondPost._id.toString(); - thirdPost._id = thirdPost._id.toString(); - } catch (err) { - console.log('error: ', err.message); - } -}); - -afterAll(async () => { - // deleting by id in case of external data - await Comment.deleteMany({ post: firstPost._id }); - await Comment.deleteMany({ post: secondPost._id }); - await Comment.deleteMany({ post: thirdPost._id }); - - await Post.deleteMany({ creator: mainUserId }); - - await Organization.findByIdAndDelete(mainOrganization._id); - - await User.findByIdAndDelete(mainUserId); - await User.findByIdAndDelete(secondUserId); - await User.findByIdAndDelete(thirdUserId); - - database.disconnect(); -}); - -describe('postsByOrganization sorting choices', () => { - test('id_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: id_ASC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('id_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: id_DESC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); - - test('text_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: text_ASC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('text_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: text_DESC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); - - test('title_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: title_ASC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('title_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: title_DESC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); - - test('createdAt_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: createdAt_ASC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('createdAt_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: createdAt_DESC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); - - test('videoUrl_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: videoUrl_ASC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('videoUrl_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: videoUrl_DESC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); - - test('imageUrl_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: imageUrl_ASC) { - _id - text - likeCount - commentCount - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('imageUrl_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: imageUrl_DESC) { - _id - text - likeCount - commentCount - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); - - test('likeCount_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: likeCount_ASC) { - _id - text - likeCount - commentCount - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('likeCount_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: likeCount_DESC) { - _id - text - likeCount - commentCount - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); - - test('commentCount_ASC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: commentCount_ASC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(firstPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(thirdPost._id); - }); - - test('commentCount_DESC', async () => { - const response = await axios.post(URL, { - query: `query { - postsByOrganization (id: "${mainOrganization._id}", orderBy: commentCount_DESC) { - _id - text - creator { - firstName - email - } - likedBy { - firstName - } - } - }`, - }); - const posts = response.data.data.postsByOrganization; - expect(Array.isArray(posts)).toBeTruthy(); - expect(posts[0]._id).toBe(thirdPost._id); - expect(posts[1]._id).toBe(secondPost._id); - expect(posts[2]._id).toBe(firstPost._id); - }); -}); diff --git a/tests/resolvers/query.spec.js b/tests/resolvers/query.spec.js deleted file mode 100644 index c3c6948009..0000000000 --- a/tests/resolvers/query.spec.js +++ /dev/null @@ -1,45 +0,0 @@ -const Query = require('../../lib/resolvers/Query'); -describe('Test from Query', () => { - test('Query should have necessary properties', () => { - expect(Query).toHaveProperty('me'); - expect(Query).toHaveProperty('user'); - expect(Query).toHaveProperty('users'); - expect(Query).toHaveProperty('usersConnection'); - - expect(Query).toHaveProperty('checkAuth'); - - expect(Query).toHaveProperty('organizations'); - expect(Query).toHaveProperty('organizationsConnection'); - expect(Query).toHaveProperty('organizationsMemberConnection'); - - expect(Query).toHaveProperty('isUserRegister'); - expect(Query).toHaveProperty('event'); - expect(Query).toHaveProperty('events'); - expect(Query).toHaveProperty('registrantsByEvent'); - expect(Query).toHaveProperty('eventsByOrganization'); - expect(Query).toHaveProperty('registeredEventsByUser'); - - expect(Query).toHaveProperty('groupChats'); - expect(Query).toHaveProperty('groupChatMessages'); - expect(Query).toHaveProperty('directChats'); - expect(Query).toHaveProperty('directChatMessages'); - expect(Query).toHaveProperty('directChatsByUserID'); - expect(Query).toHaveProperty('directChatsMessagesByChatID'); - - expect(Query).toHaveProperty('tasksByEvent'); - expect(Query).toHaveProperty('tasksByUser'); - expect(Query).toHaveProperty('comments'); - expect(Query).toHaveProperty('commentsByPost'); - expect(Query).toHaveProperty('post'); - expect(Query).toHaveProperty('posts'); - expect(Query).toHaveProperty('postsByOrganization'); - expect(Query).toHaveProperty('postsByOrganizationConnection'); - expect(Query).toHaveProperty('groups'); - - expect(Query).toHaveProperty('myLanguage'); - expect(Query).toHaveProperty('userLanguage'); - - expect(Query).toHaveProperty('getlanguage'); - expect(Query).toHaveProperty('getPlugins'); - }); -}); diff --git a/tests/resolvers/user_query/myLanguage.spec.js b/tests/resolvers/user_query/myLanguage.spec.js deleted file mode 100644 index 7e7c3ef7f4..0000000000 --- a/tests/resolvers/user_query/myLanguage.spec.js +++ /dev/null @@ -1,40 +0,0 @@ -const shortid = require('shortid'); -const database = require('../../../db'); -const getUserId = require('../../functions/getUserIdFromSignup'); -const myLanguageQuery = require('../../../lib/resolvers/user_query/myLanguage'); -const mongoose = require('mongoose'); -const { USER_NOT_FOUND } = require('../../../constants'); - -let userId; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing myLanguage resolver', () => { - test('Language of the current user', async () => { - const args = {}; - - const response = await myLanguageQuery({}, args, { - userId: userId, - }); - expect(response).toBe('en'); - }); - - test('User not exist in database', async () => { - const args = {}; - - await expect(async () => { - await myLanguageQuery({}, args, { - userId: mongoose.Types.ObjectId(), - }); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); -}); diff --git a/tests/resolvers/user_query/tasksByUser.spec.js b/tests/resolvers/user_query/tasksByUser.spec.js deleted file mode 100644 index fcc29ab62c..0000000000 --- a/tests/resolvers/user_query/tasksByUser.spec.js +++ /dev/null @@ -1,127 +0,0 @@ -const shortid = require('shortid'); -const database = require('../../../db'); -const signup = require('../../../lib/resolvers/auth_mutations/signup'); -const createOrganization = require('../../../lib/resolvers/organization_mutations/createOrganization'); -const createEvent = require('../../../lib/resolvers/event_mutations/createEvent'); -const createTask = require('../../../lib/resolvers/project_task_mutations/createTask'); -const tasksByUser = require('../../../lib/resolvers/user_query/tasksByUser'); - -let createOrgResponse; -let userId; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - - // SignUp the User - let nameForNewUser = shortid.generate().toLowerCase(); - let email = `${nameForNewUser}@test.com`; - let args = { - data: { - firstName: nameForNewUser, - lastName: nameForNewUser, - email: email, - password: 'password', - }, - }; - const signUpResponse = await signup({}, args); - - const name = shortid.generate().toLowerCase(); - const isPublic_boolean = Math.random() < 0.5; - const visibleInSearch_boolean = Math.random() < 0.5; - - args = { - data: { - name: name, - description: name, - isPublic: isPublic_boolean, - visibleInSearch: visibleInSearch_boolean, - apiUrl: name, - }, - }; - - userId = signUpResponse.user._id.toString(); - - const context = { - userId, - }; - - createOrgResponse = await createOrganization({}, args, context); - - const event_isPublic_boolean = Math.random() < 0.5; - const event_isRegisterable_boolean = Math.random() < 0.5; - const event_recurring_boolean = Math.random() < 0.5; - const event_allDay_boolean = Math.random() < 0.5; - - args = { - data: { - organizationId: createOrgResponse._id, - title: 'Talawa Conference Test', - description: 'National conference that happens yearly', - isPublic: event_isPublic_boolean, - isRegisterable: event_isRegisterable_boolean, - recurring: event_recurring_boolean, - recurrance: 'YEARLY', - location: 'Test', - startDate: '2/2/2020', - endDate: '2/2/2022', - allDay: event_allDay_boolean, - endTime: '2:00 PM', - startTime: '1:00 PM', - }, - }; - - let createEventResponse = await createEvent({}, args, context); - - args = { - eventId: createEventResponse._id, - data: { - title: 'title', - description: 'description', - status: 'ACTIVE', - }, - }; - - await createTask({}, args, context); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing tasks by user resolver', () => { - test('task by user', async () => { - const args = { - id: userId, - }; - - const response = await tasksByUser({}, args); - - expect(response).toBeTruthy(); - }); - - const orderByArgs = [ - 'id_ASC', - 'id_DESC', - 'title_ASC', - 'title_DESC', - 'description_ASC', - 'description_DESC', - 'createdAt_ASC', - 'createdAt_DESC', - 'deadline_ASC', - ]; - - orderByArgs.map((arg) => { - test(`Tasks by user with orderBy ${arg}`, async () => { - let args = { - orderBy: arg, - id: userId, - }; - - const response = await tasksByUser({}, args); - - expect(response).toBeTruthy(); - }); - }); -}); diff --git a/tests/resolvers/user_query/userLanguage.spec.js b/tests/resolvers/user_query/userLanguage.spec.js deleted file mode 100644 index 3bafc01eee..0000000000 --- a/tests/resolvers/user_query/userLanguage.spec.js +++ /dev/null @@ -1,40 +0,0 @@ -const shortid = require('shortid'); -const database = require('../../../db'); -const getUserId = require('../../functions/getUserIdFromSignup'); -const userLanguageQuery = require('../../../lib/resolvers/user_query/userLanguage'); -const mongoose = require('mongoose'); -const { USER_NOT_FOUND } = require('../../../constants'); - -let userId; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing userLanguage resolver', () => { - test('Language of existing user', async () => { - const args = { - userId, - }; - - const response = await userLanguageQuery({}, args); - expect(response).toBe('en'); - }); - - test('User not exist in database', async () => { - const args = { - userId: mongoose.Types.ObjectId(), - }; - - await expect(async () => { - await userLanguageQuery({}, args); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); -}); diff --git a/tests/resolvers/user_query/users.spec.js b/tests/resolvers/user_query/users.spec.js deleted file mode 100644 index 101f475372..0000000000 --- a/tests/resolvers/user_query/users.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -const shortid = require('shortid'); - -const database = require('../../../db'); -const getUserId = require('../../functions/getUserIdFromSignup'); -const users = require('../../../lib/resolvers/user_query/users'); - -let userId; - -beforeAll(async () => { - require('dotenv').config(); // pull env variables from .env file - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing users resolver', () => { - test('Testing basic info of any user', async () => { - const args = { - id: '62277875e904753262f99bc3', - }; - - const response = await users.user({}, args, { - userId: userId, - }); - expect(response).toBeTruthy(); - }); -}); diff --git a/tests/updateUserType.spec.js b/tests/updateUserType.spec.js deleted file mode 100644 index fd650ae17f..0000000000 --- a/tests/updateUserType.spec.js +++ /dev/null @@ -1,74 +0,0 @@ -const mongoose = require('mongoose'); -const shortid = require('shortid'); -const { USER_NOT_AUTHORIZED, USER_NOT_FOUND } = require('../constants'); - -const database = require('../db'); -const User = require('../lib/models/User'); -const updateUserType = require('../lib/resolvers/user_mutations/updateUserType'); -const getUserId = require('./functions/getUserIdFromSignup'); - -let userId; - -beforeAll(async () => { - require('dotenv').config(); - await database.connect(); - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - userId = await getUserId(generatedEmail); -}); - -afterAll(() => { - database.disconnect(); -}); - -describe('Testing update user type resolver', () => { - test('update user type', async () => { - await User.findByIdAndUpdate({ _id: userId }, { userType: 'SUPERADMIN' }); - - const args = { - data: { - id: userId, - userType: 'SUPERADMIN', - }, - }; - - const response = await updateUserType({}, args, { - userId, - }); - - expect(response).toBeTruthy(); - }); - - test('Testing, when user is not super admin', async () => { - await User.findByIdAndUpdate({ _id: userId }, { userType: 'ADMIN' }); - - const args = { - data: { - id: userId, - userType: 'SUPERADMIN', - }, - }; - - await expect(async () => { - await updateUserType({}, args, { - userId, - }); - }).rejects.toEqual(Error(USER_NOT_AUTHORIZED)); - }); - - test('Testing, when user is not found', async () => { - await User.findByIdAndUpdate({ _id: userId }, { userType: 'SUPERADMIN' }); - - const args = { - data: { - id: mongoose.Types.ObjectId(), - userType: 'SUPERADMIN', - }, - }; - - await expect(async () => { - await updateUserType({}, args, { - userId, - }); - }).rejects.toEqual(Error(USER_NOT_FOUND)); - }); -}); diff --git a/tests/user_me_query.spec.js b/tests/user_me_query.spec.js deleted file mode 100644 index d6fa93c451..0000000000 --- a/tests/user_me_query.spec.js +++ /dev/null @@ -1,177 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const getUserId = require('./functions/getUserId'); -const shortid = require('shortid'); - -let token; -let userId; -let generatedEmail; -beforeAll(async () => { - generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); -}); - -describe('user resolvers', () => { - test('Get Logged In User details - me Query', async () => { - const response = await axios.post( - URL, - { - query: ` - { - me { - _id - firstName - lastName - email - userType - appLanguageCode - createdOrganizations { - _id - name - description - isPublic - visibleInSearch - apiUrl - creator { - _id - firstName - } - members { - _id - firstName - } - admins { - _id - firstName - } - membershipRequests { - _id - } - blockedUsers{ - _id - } - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = response; - - expect(data.data.me).toEqual( - expect.objectContaining({ - _id: userId, - firstName: 'testdb2', - lastName: 'testdb2', - email: generatedEmail, - userType: 'USER', - appLanguageCode: expect.any(String), - }) - ); - - //Array of Organizations - const userCreatedOrganizationsData = data.data.me.createdOrganizations; - - // Asserting each Organization by mapping - userCreatedOrganizationsData.map((org) => { - if (!org) { - return; - } - expect(org).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - apiUrl: expect.any(String), - creator: expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }), - }) - ); - - // Asserting each Organization's Members Array - org.members.map((member) => { - expect(member).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - // Asserting each Organization's Admins Array - org.admins.map((admin) => { - expect(admin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - // Asserting each Organization's membershipRequests Array - org.membershipRequests.map((membershipRequest) => { - expect(membershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // Asserting each Organization's blockedUsers Array - org.blockedUsers.map((blockedUser) => { - expect(blockedUser).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - }); - }); - - test('me Query without Authorization', async () => { - const response = await axios.post(URL, { - query: ` - { - me { - _id - firstName - lastName - email - userType - appLanguageCode - } - } - `, - }); - - expect(response.data.errors[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - status: 422, - }) - ); - - expect(response.data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - code: 'user.notAuthenticated', - param: 'userAuthentication', - metadata: {}, - }) - ); - - expect(response.data.data).toEqual(null); - }); -}); diff --git a/tests/user_organization.spec.js b/tests/user_organization.spec.js deleted file mode 100644 index fe0af2daab..0000000000 --- a/tests/user_organization.spec.js +++ /dev/null @@ -1,463 +0,0 @@ -const axios = require('axios'); -const logger = require('logger'); -const shortid = require('shortid'); -const { - URL, - MEMBER_NOT_FOUND, - MEMBER_NOT_FOUND_CODE, - MEMBER_NOT_FOUND_PARAM, - USER_NOT_AUTHORIZED, - USER_NOT_AUTHORIZED_CODE, - USER_ALREADY_MEMBER_PARAM, -} = require('../constants'); -const getToken = require('./functions/getToken'); - -let token; -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -let createdOrgId = 'test'; -let createdUserId; - -describe('User-Organization Resolvers', () => { - // ORGANIZATION IS CREATED - - test('createOrganization', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - createOrganization(data: { - name:"test org" - description:"test description" - isPublic: true - visibleInSearch: true - }) { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - if (!data.data) { - logger.info('Data not present'); - } - createdOrgId = data.data.createOrganization._id; - expect(data.data.createOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // NEW USER IS CREATED - - let newUserToken; - let newUserId; - test('signUp', async () => { - const id = shortid.generate(); - const email = `${id}@test.com`; - const response = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"testdb2", - lastName:"testdb2" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const { data } = response; - newUserToken = data.data.signUp.accessToken; - newUserId = data.data.signUp.user._id; - expect(data.data.signUp).toEqual( - expect.objectContaining({ - accessToken: expect.any(String), - }) - ); - }); - - // NEW USER JOINS ORGANIZATION - test('Join Public Organization', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - joinPublicOrganization(organizationId: "${createdOrgId}") { - _id - firstName - lastName - email - } - }`, - }, - { - headers: { - Authorization: `Bearer ${newUserToken}`, - }, - } - ); - const { data } = response; - expect(data.data.joinPublicOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - }) - ); - }); - - // NEW USER CREATES A GROUP - - // USER IS MADE ADMIN - test('User is made admin', async () => { - const response = await axios.post( - URL, - { - query: `mutation { - createAdmin(data: { - organizationId: "${createdOrgId}" - userId: "${newUserId}" - }) { - _id - firstName - lastName - email - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = response; - expect(data.data.createAdmin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - }) - ); - }); - - test('Attempt to make user as admin if already is an admin', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - createAdmin(data: { - organizationId: "${createdOrgId}" - userId: "${newUserId}" - }) { - _id - firstName - lastName - email - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = response; - expect(data.errors[0]).toEqual( - expect.objectContaining({ - message: USER_NOT_AUTHORIZED, - status: 422, - }) - ); - - expect(data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: USER_NOT_AUTHORIZED, - code: USER_NOT_AUTHORIZED_CODE, - param: USER_ALREADY_MEMBER_PARAM, - metadata: {}, - }) - ); - - expect(data.data).toEqual(null); - }); - - // ADMIN REMOVES GROUP - - // ADMIN REMOVES EVENT - - // ADMIN IS REMOVED - - test('Admin is removed', async () => { - const response = await axios.post( - URL, - { - query: `mutation { - removeAdmin(data: { - organizationId: "${createdOrgId}" - userId: "${newUserId}" - }) { - _id - firstName - lastName - email - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = response; - expect(data.data.removeAdmin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - }) - ); - }); - - // USER LEAVES ORGANIZATION - - test('Leave Organization', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - leaveOrganization(organizationId: "${createdOrgId}") { - _id - firstName - lastName - email - } - }`, - }, - { - headers: { - Authorization: `Bearer ${newUserToken}`, - }, - } - ); - - const { data } = response; - expect(data.data.leaveOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - }) - ); - }); - - test('User Attempt to Leave Organization if already leaved', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation { - leaveOrganization(organizationId: "${createdOrgId}") { - _id - firstName - lastName - email - } - }`, - }, - { - headers: { - Authorization: `Bearer ${newUserToken}`, - }, - } - ); - - const { data } = response; - - expect(Array.isArray(data.errors)).toBeTruthy(); - - expect(data.errors[0]).toEqual( - expect.objectContaining({ - message: MEMBER_NOT_FOUND, - status: 422, - }) - ); - - expect(data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: MEMBER_NOT_FOUND, - code: MEMBER_NOT_FOUND_CODE, - param: MEMBER_NOT_FOUND_PARAM, - metadata: {}, - }) - ); - - expect(data.data).toEqual(null); - }); - - // ADMIN REMOVES USER FROM ORGANIZATION - - // A NEW USER HAS TO BE CREATED THEN ADDED TO THE ORGANIZATION THEN REMOVED - test('Remove Member from organization', async () => { - // new user is created - const id = shortid.generate(); - const email = `${id}@test.com`; - - const signUpResponse = await axios.post(URL, { - query: ` - mutation { - signUp(data: { - firstName:"testdb2", - lastName:"testdb2" - email: "${email}" - password:"password" - }) { - user{ - _id - } - accessToken - } - } - `, - }); - const { data } = signUpResponse; - const userToken = data.data.signUp.accessToken; - createdUserId = data.data.signUp.user._id; - - // user joins organizations - await axios.post( - URL, - { - query: ` - mutation { - joinPublicOrganization(organizationId: "${createdOrgId}") { - _id - firstName - lastName - email - } - }`, - }, - { - headers: { - Authorization: `Bearer ${userToken}`, - }, - } - ); - // Admin removes user from organization - const removeMemberResponse = await axios.post( - URL, - { - query: `mutation { - removeMember(data: { - organizationId: "${createdOrgId}", - userIds: ["${createdUserId}"] - }) { - _id - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const removeMemberData = removeMemberResponse.data; - expect(removeMemberData.data.removeMember).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - test('Attempt to remove member if already removed', async () => { - const removeMemberResponse = await axios.post( - URL, - { - query: `mutation { - removeMember(data: { - organizationId: "${createdOrgId}", - userIds: ["${createdUserId}"] - }) { - _id - } - }`, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = removeMemberResponse; - expect(Array.isArray(data.errors)).toBeTruthy(); - - expect(data.errors[0]).toEqual( - expect.objectContaining({ - message: MEMBER_NOT_FOUND, - status: 422, - data: [], - }) - ); - - expect(data.data).toEqual(null); - }); - - // ORGANIZATION IS DELETED - - test('deleteOrganization', async () => { - const deletedResponse = await axios.post( - URL, - { - query: ` - mutation { - removeOrganization(id: "${createdOrgId}") { - _id - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - expect(deletedResponse.data.data.removeOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); -}); diff --git a/tests/user_query_with_id.spec.js b/tests/user_query_with_id.spec.js deleted file mode 100644 index f4d9402bf2..0000000000 --- a/tests/user_query_with_id.spec.js +++ /dev/null @@ -1,177 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const getUserId = require('./functions/getUserId'); -const shortid = require('shortid'); - -let token; -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); -}); - -describe('user query', () => { - test('Get Logged In User Details', async () => { - const response = await axios.post( - URL, - { - query: ` - { - user(id: "${userId}") { - _id - firstName - lastName - email - userType - appLanguageCode - - createdOrganizations { - _id - name - description - isPublic - visibleInSearch - apiUrl - creator { - _id - firstName - } - members { - _id - firstName - } - admins { - _id - firstName - } - membershipRequests { - _id - } - blockedUsers { - _id - } - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = response; - expect(data.data.user).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - userType: expect.any(String), - appLanguageCode: expect.any(String), - }) - ); - - //Array of Organizations - const userCreatedOrganizationsData = data.data.user.createdOrganizations; - - // Asserting each Organization by mapping - userCreatedOrganizationsData.map((org) => { - if (!org) { - return; - } - expect(org).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - description: expect.any(String), - isPublic: expect.any(Boolean), - visibleInSearch: expect.any(Boolean), - apiUrl: expect.any(String), - creator: expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }), - }) - ); - - // Asserting each Organization's Members Array - org.members.map((member) => { - expect(member).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - // Asserting each Organization's Admins Array - org.admins.map((admin) => { - expect(admin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - }) - ); - }); - - // Asserting each Organization's membershipRequests Array - org.membershipRequests.map((membershipRequest) => { - expect(membershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - // Asserting each Organization's blockedUsers Array - org.blockedUsers.map((blockedUser) => { - expect(blockedUser).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - }); - }); - - test('User Query without Authorization', async () => { - const response = await axios.post(URL, { - query: ` - { - user(id: "${userId}") { - _id - firstName - lastName - email - userType - appLanguageCode - } - } - `, - }); - - expect(response.data.errors[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - status: 422, - }) - ); - - expect(response.data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - code: 'user.notAuthenticated', - param: 'userAuthentication', - metadata: {}, - }) - ); - - expect(response.data.data).toEqual(null); - }); -}); diff --git a/tests/user_subqueries.spec.js b/tests/user_subqueries.spec.js deleted file mode 100644 index aa70968de4..0000000000 --- a/tests/user_subqueries.spec.js +++ /dev/null @@ -1,183 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const shortid = require('shortid'); - -let token; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('users resolvers', () => { - test('users query', async () => { - const response = await axios.post( - URL, - { - query: `query { - users { - _id - firstName - lastName - email - createdOrganizations { - _id - name - } - joinedOrganizations { - _id - name - } - createdEvents { - _id - } - registeredEvents { - _id - } - eventAdmin { - _id - } - adminFor { - _id - name - } - membershipRequests { - _id - } - organizationsBlockedBy{ - _id - } - } - } - `, - }, - { - headers: { - authorization: `Bearer ${token}`, - }, - } - ); - const { data } = response; - expect(Array.isArray(data.data.users)).toBeTruthy(); - const firstUser = data.data.users[0]; - //Tested First Object in Array as others will be similar. - expect(firstUser).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - }) - ); - firstUser.createdOrganizations.map((createdOrganization) => { - expect(createdOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - }) - ); - }); - - firstUser.joinedOrganizations.map((joinedOrganization) => { - expect(joinedOrganization).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - }) - ); - }); - - firstUser.createdEvents.map((createdEvent) => { - expect(createdEvent).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - firstUser.registeredEvents.map((registeredEvent) => { - expect(registeredEvent).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - firstUser.eventAdmin.map((admin) => { - expect(admin).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - firstUser.adminFor.map((org) => { - expect(org).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - }) - ); - }); - - firstUser.membershipRequests.map((membershipRequest) => { - expect(membershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - firstUser.organizationsBlockedBy.map((org) => { - expect(org).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - }); - - test('users query without Authorization', async () => { - const response = await axios.post(URL, { - query: `query { - users { - _id - firstName - lastName - email - createdOrganizations { - _id - name - } - joinedOrganizations { - _id - name - } - } - } - `, - }); - const { data } = response; - - expect(Array.isArray(data.errors)).toBeTruthy(); - - expect(data.errors[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - status: 422, - }) - ); - - expect(data.errors[0].data[0]).toEqual( - expect.objectContaining({ - message: 'User is not authenticated', - code: 'user.notAuthenticated', - param: 'userAuthentication', - metadata: {}, - }) - ); - - expect(data.data.users).toEqual(null); - }); -}); diff --git a/tests/user_update.spec.js b/tests/user_update.spec.js deleted file mode 100644 index 965f34fbe5..0000000000 --- a/tests/user_update.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const shortid = require('shortid'); - -let token; -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); -}); - -describe('Update-Profile Resolvers', () => { - let id = shortid.generate().toLowerCase(); - let email = `${id}@test.com`; - - test('updateProfile', async () => { - const response = await axios.post( - URL, - { - query: ` - mutation{ - updateUserProfile(data:{ - firstName:"Test" - lastName:"Name" - email:"${email}" - }){ - firstName - lastName - email - } - } - `, - }, - { - headers: { - authorization: `Bearer ${token}`, - }, - } - ); - - const { data } = response; - expect(data.data.updateUserProfile).toEqual( - expect.objectContaining({ - firstName: 'Test', - lastName: 'Name', - email: email, - }) - ); - }); -}); diff --git a/tests/users_connection.spec.js b/tests/users_connection.spec.js deleted file mode 100644 index e6c783c25f..0000000000 --- a/tests/users_connection.spec.js +++ /dev/null @@ -1,183 +0,0 @@ -const axios = require('axios'); -const { URL } = require('../constants'); -const getToken = require('./functions/getToken'); -const getUserId = require('./functions/getUserId'); -const shortid = require('shortid'); - -let token; -let userId; - -beforeAll(async () => { - let generatedEmail = `${shortid.generate().toLowerCase()}@test.com`; - token = await getToken(generatedEmail); - userId = await getUserId(generatedEmail); -}); - -describe('users connection query', () => { - test('users connection without parameters', async () => { - const usersConnectionResponse = await axios.post( - URL, - { - query: ` - { - usersConnection { - _id - firstName - lastName - email - userType - createdOrganizations { - _id - } - joinedOrganizations { - _id - name - } - createdEvents { - _id - } - registeredEvents { - _id - } - eventAdmin { - _id - } - adminFor { - _id - } - membershipRequests { - _id - } - organizationsBlockedBy { - _id - name - } - organizationUserBelongsTo { - _id - } - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = usersConnectionResponse; - const usersConnectionData = data.data.usersConnection; - usersConnectionData.map((user) => { - expect(user).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - }) - ); - - user.createdOrganizations.map((org) => { - expect(org).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - user.joinedOrganizations.map((org) => { - expect(org).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - }) - ); - }); - - user.createdEvents.map((createdEvent) => { - expect(createdEvent).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - user.registeredEvents.map((registeredEvent) => { - expect(registeredEvent).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - user.eventAdmin.map((event) => { - expect(event).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - user.adminFor.map((obj) => { - expect(obj).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - user.membershipRequests.map((membershipRequest) => { - expect(membershipRequest).toEqual( - expect.objectContaining({ - _id: expect.any(String), - }) - ); - }); - - user.organizationsBlockedBy.map((obj) => { - expect(obj).toEqual( - expect.objectContaining({ - _id: expect.any(String), - name: expect.any(String), - }) - ); - }); - - expect(user.organizationUserBelongsTo).toEqual(null); - }); - }); - - test('users connection with Id', async () => { - const usersConnectionResponse = await axios.post( - URL, - { - query: ` - { - usersConnection(where:{id:"${userId}"}) { - _id - firstName - lastName - email - } - } - `, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ); - const { data } = usersConnectionResponse; - expect(data.data.usersConnection).toHaveLength(1); - - expect(data.data.usersConnection[0]).toEqual( - expect.objectContaining({ - _id: expect.any(String), - firstName: expect.any(String), - lastName: expect.any(String), - email: expect.any(String), - }) - ); - }); -}); diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000000..a0829eeaed --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "module": "commonjs" /* Specify what module code is generated. */, + "rootDir": "./src" /* Specify the root folder within your source files. */, + "outDir": "./build" /* Specify an output folder for all emitted files. */, + "removeComments": true /* Disable emitting comments. */, + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + "strict": true /* Enable all strict type-checking options. */, + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["./src"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..531c2f93e9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "module": "commonjs" /* Specify what module code is generated. */, + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + "strict": true /* Enable all strict type-checking options. */, + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["./src","./__tests__"] +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000000..33e16293a3 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,36 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + coverage: { + // This tells vitest to include those files from src/lib in test coverage + // as well that don't have an associated test written for them. + all: true, + // This tells vitests the directory to get coverage for. + include: ["src/lib"], + // This tells vitest to exclude files from src/lib directory from the coverage. + // This is intentionally done because these files don't provide any meaningful + // coverage in test coverage report. + exclude: [ + "src/lib/config", + "src/lib/directives/index.ts", + "src/lib/libraries/**/*index.ts", + "src/lib/middleware/index.ts", + "src/lib/models", + "src/lib/resolvers/**/*index.ts", + "src/lib/typeDefs", + "src/lib/utilities/index.ts", + ], + // This is used to tell vitest which coverage provider to use. c8 is the default + // and newer coverage provider for node.js applications. You can swap it with + // istanbul as well. + provider: "c8", + // This tells vitest in what format the report will be generated. Here lcov + // is selected because a file named lcov.info is generated by this reporter which + // is used in codecov/codecov-action github action. + reporter: ["lcov"], + }, + // Tells vitest the time limit for an individual test block run. + testTimeout: 30000, + }, +});