diff --git a/.babelrc b/.babelrc index 9151969bde..c2eeb06f9e 100644 --- a/.babelrc +++ b/.babelrc @@ -6,8 +6,9 @@ "presets": [ ["@babel/preset-env", { "targets": { - "node": "12" - } + "node": "14", + }, + "exclude": ["proposal-dynamic-import"] }] ], "sourceMaps": "inline" diff --git a/.dockerignore b/.dockerignore index da15e92511..693f3e35b5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,8 +1,6 @@ node_modules npm-debug.log *.md -PATENTS -LICENSE Dockerfile .dockerignore .gitignore diff --git a/.eslintrc.json b/.eslintrc.json index 7e6bdec06a..c04e2d3109 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,13 +5,14 @@ "node": true, "es6": true }, - "parser": "babel-eslint", + "parser": "@babel/eslint-parser", "plugins": [ "flowtype" ], "parserOptions": { "ecmaVersion": 6, - "sourceType": "module" + "sourceType": "module", + "requireConfigFile": false }, "rules": { "indent": ["error", 2, { "SwitchCase": 1 }], @@ -24,5 +25,8 @@ "space-infix-ops": "error", "no-useless-escape": "off", "require-atomic-updates": "off" + }, + "globals": { + "Parse": true } } diff --git a/.flowconfig b/.flowconfig index e36f404424..955444c1c0 100644 --- a/.flowconfig +++ b/.flowconfig @@ -8,3 +8,4 @@ [options] suppress_comment= \\(.\\|\n\\)*\\@flow-disable-next +esproposal.optional_chaining=enable diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..ebfc2b23c8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +# Dependabot dependency updates +# Docs: https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "npm" + # Location of package-lock.json + directory: "/" + # Check daily for updates + schedule: + interval: "daily" + commit-message: + # Set commit message prefix + prefix: "refactor" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 72dba372a9..a61c8e9625 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,29 +1,21 @@ -### New Pull Request Checklist - +## Pull Request -- [ ] I am not disclosing a [vulnerability](https://github.com/parse-community/parse-server/blob/master/SECURITY.md). -- [ ] I am creating this PR in reference to an [issue](https://github.com/parse-community/parse-server/issues?q=is%3Aissue). +- Report security issues [confidentially](https://github.com/parse-community/parse-server/security/policy). +- Any contribution is under this [license](https://github.com/parse-community/parse-server/blob/alpha/LICENSE). +- Link this pull request to an [issue](https://github.com/parse-community/parse-server/issues?q=is%3Aissue). -### Issue Description - +## Issue + -Related issue: FILL_THIS_OUT +Closes: FILL_THIS_OUT -### Approach - +## Approach + -### TODOs before merging - +## Tasks + - [ ] Add tests -- [ ] Add changes to documentation (guides, repository pages, in-code descriptions) +- [ ] Add changes to documentation (guides, repository pages, code comments) - [ ] Add [security check](https://github.com/parse-community/parse-server/blob/master/CONTRIBUTING.md#security-checks) - [ ] Add new Parse Error codes to Parse JS SDK -- [x] A changelog entry is created automatically using the pull request title (do not manually add a changelog entry) diff --git a/.github/workflows/ci-automated-check-environment.yml b/.github/workflows/ci-automated-check-environment.yml index 0f08d2e47a..ae83f879f1 100644 --- a/.github/workflows/ci-automated-check-environment.yml +++ b/.github/workflows/ci-automated-check-environment.yml @@ -13,13 +13,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout default branch - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v2 with: node-version: 14 - name: Cache Node.js modules - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout default branch - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Compose branch name for PR id: branch run: echo "::set-output name=name::ci-bump-environment" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71fe415f7f..711a844574 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,14 @@ name: ci on: push: - branches: [ release, alpha, beta ] + branches: [release, alpha, beta, next-major, 'release-[0-9]+.x.x'] pull_request: - branches: [ release, alpha, beta ] + branches: + - '**' + paths-ignore: + - '**/**.md' env: - NODE_VERSION: 18.1.0 + NODE_VERSION: 20.11.1 PARSE_SERVER_TEST_TIMEOUT: 20000 jobs: check-code-analysis: @@ -18,29 +21,29 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ['javascript'] steps: - - name: Checkout repository - uses: actions/checkout@v3 - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - source-root: src - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + - name: Checkout repository + uses: actions/checkout@v4 + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + source-root: src + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 check-ci: name: Node Engine Check timeout-minutes: 15 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.NODE_VERSION }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - name: Cache Node.js modules - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} @@ -51,141 +54,135 @@ jobs: - name: CI Node Engine Check run: npm run ci:checkNodeEngine check-lint: - name: Lint - timeout-minutes: 15 - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.NODE_VERSION }} - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - - name: Cache Node.js modules - uses: actions/cache@v2 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}- - - name: Install dependencies - run: npm ci - - run: npm run lint + name: Lint + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - name: Cache Node.js modules + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}- + - name: Install dependencies + run: npm ci + - run: npm run lint + check-definitions: + name: Check Definitions + timeout-minutes: 5 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - name: Cache Node.js modules + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}- + - name: Install dependencies + run: npm ci + - name: CI Definitions Check + run: npm run ci:definitionsCheck check-circular: - name: Circular Dependencies - timeout-minutes: 5 - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.NODE_VERSION }} - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - - name: Cache Node.js modules - uses: actions/cache@v2 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}- - - name: Install dependencies - run: npm ci - - run: npm run madge:circular + name: Circular Dependencies + timeout-minutes: 5 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - name: Cache Node.js modules + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}- + - name: Install dependencies + run: npm ci + - run: npm run madge:circular check-docker: name: Docker Build timeout-minutes: 15 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Build docker image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . - platforms: linux/amd64 + platforms: linux/amd64, linux/arm64/v8 check-lock-file-version: name: NPM Lock File Version timeout-minutes: 5 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Check NPM lock file version uses: mansona/npm-lockfile-version@v1 with: - version: 1 + version: 2 check-mongo: strategy: matrix: include: - - name: MongoDB 4.0, Standalone, MMAPv1 - MONGODB_VERSION: 4.0.28 - MONGODB_TOPOLOGY: standalone - MONGODB_STORAGE_ENGINE: mmapv1 - NODE_VERSION: 18.1.0 - - name: MongoDB 4.0, ReplicaSet, WiredTiger - MONGODB_VERSION: 4.0.28 - MONGODB_TOPOLOGY: replicaset - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 18.1.0 - - name: MongoDB 4.2, ReplicaSet, WiredTiger + - name: MongoDB 4.2, ReplicaSet MONGODB_VERSION: 4.2.19 - MONGODB_TOPOLOGY: replicaset - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 18.1.0 - - name: MongoDB 4.4, ReplicaSet, WiredTiger + MONGODB_TOPOLOGY: replset + NODE_VERSION: 20.11.1 + - name: MongoDB 4.4, ReplicaSet MONGODB_VERSION: 4.4.13 - MONGODB_TOPOLOGY: replicaset - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 18.1.0 - - name: MongoDB 5, ReplicaSet, WiredTiger + MONGODB_TOPOLOGY: replset + NODE_VERSION: 20.11.1 + - name: MongoDB 5, ReplicaSet MONGODB_VERSION: 5.3.2 - MONGODB_TOPOLOGY: replicaset - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 18.1.0 - - name: MongoDB 6, ReplicaSet, WiredTiger + MONGODB_TOPOLOGY: replset + NODE_VERSION: 20.11.1 + - name: MongoDB 6, ReplicaSet MONGODB_VERSION: 6.0.2 - MONGODB_TOPOLOGY: replicaset - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 18.1.0 + MONGODB_TOPOLOGY: replset + NODE_VERSION: 20.11.1 + - name: MongoDB 7, ReplicaSet + MONGODB_VERSION: 7.0.1 + MONGODB_TOPOLOGY: replset + NODE_VERSION: 20.11.1 - name: Redis Cache PARSE_SERVER_TEST_CACHE: redis MONGODB_VERSION: 4.4.13 MONGODB_TOPOLOGY: standalone - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 18.1.0 - - name: Node 12 - MONGODB_VERSION: 4.4.13 - MONGODB_TOPOLOGY: standalone - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 12.22.11 - - name: Node 14 + NODE_VERSION: 20.11.1 + - name: Node 18 MONGODB_VERSION: 4.4.13 MONGODB_TOPOLOGY: standalone - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 14.19.1 - - name: Node 16 - MONGODB_VERSION: 4.4.13 - MONGODB_TOPOLOGY: standalone - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 16.14.2 - - name: Node 17 - MONGODB_VERSION: 4.4.13 - MONGODB_TOPOLOGY: standalone - MONGODB_STORAGE_ENGINE: wiredTiger - NODE_VERSION: 17.9.0 + NODE_VERSION: 18.19.1 fail-fast: false name: ${{ matrix.name }} timeout-minutes: 15 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest services: redis: image: redis ports: - - 6379:6379 + - 6379:6379 env: MONGODB_VERSION: ${{ matrix.MONGODB_VERSION }} MONGODB_TOPOLOGY: ${{ matrix.MONGODB_TOPOLOGY }} @@ -195,13 +192,13 @@ jobs: steps: - name: Fix usage of insecure GitHub protocol run: sudo git config --system url."https://github".insteadOf "git://github" - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.NODE_VERSION }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.NODE_VERSION }} - name: Cache Node.js modules - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} @@ -218,34 +215,31 @@ jobs: strategy: matrix: include: - - name: PostgreSQL 11, PostGIS 3.0 - POSTGRES_IMAGE: postgis/postgis:11-3.0 - NODE_VERSION: 18.1.0 - - name: PostgreSQL 11, PostGIS 3.1 - POSTGRES_IMAGE: postgis/postgis:11-3.1 - NODE_VERSION: 18.1.0 - - name: PostgreSQL 11, PostGIS 3.2 - POSTGRES_IMAGE: postgis/postgis:11-3.2 - NODE_VERSION: 18.1.0 - - name: PostgreSQL 11, PostGIS 3.3 - POSTGRES_IMAGE: postgis/postgis:11-3.3 - NODE_VERSION: 18.1.0 - - name: PostgreSQL 12, PostGIS 3.3 - POSTGRES_IMAGE: postgis/postgis:12-3.3 - NODE_VERSION: 18.1.0 + - name: PostgreSQL 13, PostGIS 3.1 + POSTGRES_IMAGE: postgis/postgis:13-3.1 + NODE_VERSION: 20.11.1 + - name: PostgreSQL 13, PostGIS 3.2 + POSTGRES_IMAGE: postgis/postgis:13-3.2 + NODE_VERSION: 20.11.1 - name: PostgreSQL 13, PostGIS 3.3 POSTGRES_IMAGE: postgis/postgis:13-3.3 - NODE_VERSION: 18.1.0 - - name: PostgreSQL 14, PostGIS 3.3 - POSTGRES_IMAGE: postgis/postgis:14-3.3 - NODE_VERSION: 18.1.0 - - name: PostgreSQL 15, PostGIS 3.3 - POSTGRES_IMAGE: postgis/postgis:15-3.3 - NODE_VERSION: 18.1.0 + NODE_VERSION: 20.11.1 + - name: PostgreSQL 13, PostGIS 3.4 + POSTGRES_IMAGE: postgis/postgis:13-3.4 + NODE_VERSION: 20.11.1 + - name: PostgreSQL 14, PostGIS 3.4 + POSTGRES_IMAGE: postgis/postgis:14-3.4 + NODE_VERSION: 20.11.1 + - name: PostgreSQL 15, PostGIS 3.4 + POSTGRES_IMAGE: postgis/postgis:15-3.4 + NODE_VERSION: 20.11.1 + - name: PostgreSQL 16, PostGIS 3.4 + POSTGRES_IMAGE: postgis/postgis:15-3.4 + NODE_VERSION: 20.11.1 fail-fast: false name: ${{ matrix.name }} timeout-minutes: 15 - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest services: redis: image: redis @@ -267,13 +261,13 @@ jobs: PARSE_SERVER_TEST_DATABASE_URI: postgres://postgres:postgres@localhost:5432/parse_server_postgres_adapter_test_database NODE_VERSION: ${{ matrix.NODE_VERSION }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.NODE_VERSION }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.NODE_VERSION }} - name: Cache Node.js modules - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }} diff --git a/.github/workflows/release-automated-scheduler.yml b/.github/workflows/release-automated-scheduler.yml deleted file mode 100644 index d67b102e27..0000000000 --- a/.github/workflows/release-automated-scheduler.yml +++ /dev/null @@ -1,74 +0,0 @@ -# This scheduler creates pull requests to prepare for releases in intervals according to the -# release cycle of this repository. - -name: release-automated-scheduler -on: -# Scheduler temporarily disabled until stable release of Parse Server 5 with all branches (alpha, beta, release) created -# schedule: -# - cron: 0 0 1 * * - workflow_dispatch: - -jobs: - create-pr-release: - runs-on: ubuntu-latest - steps: - - name: Checkout beta branch - uses: actions/checkout@v2 - with: - ref: beta - - name: Compose branch name for PR - id: branch - run: echo "::set-output name=name::build-release-${{ github.run_id }}${{ github.run_number }}" - - name: Create branch - run: | - git config --global user.email ${{ github.actor }}@users.noreply.github.com - git config --global user.name ${{ github.actor }} - git checkout -b ${{ steps.branch.outputs.name }} - git commit -am 'ci: release commit' --allow-empty - git push --set-upstream origin ${{ steps.branch.outputs.name }} - - name: Create PR - uses: k3rnels-actions/pr-update@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - pr_title: "build: release" - pr_source: ${{ steps.branch.outputs.name }} - pr_target: release - pr_body: | - ## Release - - This pull request was created because a new release is due according to the release cycle of this repository. - Just resolve any conflicts and it's good to merge. Any version increment will be done by release automation. - - *⚠️ Use `Merge commit` to merge this pull request. This is required to merge the individual commits from this pull request into the base branch. Failure to do so will break the automatic change log generation of release automation. Do not use "Squash and merge"!* - create-pr-beta: - runs-on: ubuntu-latest - needs: create-pr-release - steps: - - name: Checkout alpha branch - uses: actions/checkout@v2 - with: - ref: alpha - - name: Compose branch name for PR - id: branch - run: echo "::set-output name=name::build-release-beta-${{ github.run_id }}${{ github.run_number }}" - - name: Create branch - run: | - git config --global user.email ${{ github.actor }}@users.noreply.github.com - git config --global user.name ${{ github.actor }} - git checkout -b ${{ steps.branch.outputs.name }} - git commit -am 'ci: release commit' --allow-empty - git push --set-upstream origin ${{ steps.branch.outputs.name }} - - name: Create PR - uses: k3rnels-actions/pr-update@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - pr_title: "build: release beta" - pr_source: ${{ steps.branch.outputs.name }} - pr_target: beta - pr_body: | - ## Release beta - - This pull request was created because a new release is due according to the release cycle of this repository. - Just resolve any conflicts and it's good to merge. Any version increment will be done by release automation. - - *⚠️ Use `Merge commit` to merge this pull request. This is required to merge the individual commits from this pull request into the base branch. Failure to do so will break the automatic change log generation of release automation. Do not use "Squash and merge"!* diff --git a/.github/workflows/release-automated.yml b/.github/workflows/release-automated.yml index 35dae71bec..21f5bb31e7 100644 --- a/.github/workflows/release-automated.yml +++ b/.github/workflows/release-automated.yml @@ -1,7 +1,7 @@ name: release-automated on: push: - branches: [ release, alpha, beta, next-major ] + branches: [ release, alpha, beta, next-major, 'release-[0-9]+.x.x' ] jobs: release: runs-on: ubuntu-latest @@ -12,15 +12,15 @@ jobs: - name: Determine trigger branch name id: branch run: echo "::set-output name=trigger_branch::${GITHUB_REF#refs/*/}" - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: persist-credentials: false - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 18.19.1 registry-url: https://registry.npmjs.org/ - name: Cache Node.js modules - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -42,7 +42,7 @@ jobs: env: REGISTRY: docker.io IMAGE_NAME: parseplatform/parse-server - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest permissions: contents: read packages: write @@ -51,23 +51,23 @@ jobs: id: branch run: echo "::set-output name=branch_name::${GITHUB_REF#refs/*/}" - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: ${{ needs.release.outputs.current_tag }} - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Log into Docker Hub if: github.event_name != 'pull_request' - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} flavor: | @@ -75,10 +75,10 @@ jobs: tags: | type=semver,pattern={{version}},value=${{ needs.release.outputs.current_tag }} - name: Build and push Docker image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . - platforms: linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64/v8 + platforms: linux/amd64, linux/arm64/v8 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} @@ -86,16 +86,16 @@ jobs: docs: needs: release if: needs.release.outputs.current_tag != '' && github.ref == 'refs/heads/release' - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 18.19.1 - name: Cache Node.js modules - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -112,4 +112,4 @@ jobs: uses: peaceiris/actions-gh-pages@v3.7.3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs \ No newline at end of file + publish_dir: ./docs diff --git a/.github/workflows/release-manual-docker.yml b/.github/workflows/release-manual-docker.yml index 3300f2a498..3b7ee8c0ab 100644 --- a/.github/workflows/release-manual-docker.yml +++ b/.github/workflows/release-manual-docker.yml @@ -14,7 +14,7 @@ env: IMAGE_NAME: parseplatform/parse-server jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest permissions: contents: read packages: write @@ -23,23 +23,23 @@ jobs: id: branch run: echo "::set-output name=branch_name::${GITHUB_REF#refs/*/}" - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: ${{ github.event.inputs.ref }} - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Log into Docker Hub if: github.event_name != 'pull_request' - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} flavor: | @@ -48,10 +48,10 @@ jobs: type=semver,enable=true,pattern={{version}},value=${{ github.event.inputs.ref }} type=raw,enable=${{ github.event.inputs.ref == '' }},value=latest - name: Build and push Docker image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: context: . - platforms: linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64/v8 + platforms: linux/amd64, linux/arm64/v8 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/2.3.0.md b/2.3.0.md deleted file mode 100644 index 42a19263fc..0000000000 --- a/2.3.0.md +++ /dev/null @@ -1,82 +0,0 @@ -# Upgrading Parse Server to version 2.3.0 - -Parse Server version 2.3.0 begins using unique indexes to ensure the User's username and email are unique. This is not a backwards incompatible change, but it may in some cases cause a significant performance regression until the index finishes building. Building the unique index before upgrading your Parse Server version will eliminate the performance impact, and is a recommended step before upgrading any app to Parse Server 2.3.0. New apps starting with version 2.3.0 do not need to take any steps before beginning their project. - -If you are using MongoDB in Cluster or Replica Set mode, we recommend reading Mongo's [documentation on index building](https://docs.mongodb.com/v3.0/tutorial/build-indexes-on-replica-sets/) first. If you are not using these features, you can execute the following commands from the Mongo shell to build the unique index. You may also want to create a backup first. - -```js -// Select the database that your Parse App uses -use parse; - -// Select the collection your Parse App uses for users. For migrated apps, this probably includes a collectionPrefix. -var coll = db['your_prefix:_User']; - -// You can check if the indexes already exists by running coll.getIndexes() -coll.getIndexes(); - -// The indexes you want should look like this. If they already exist, you can skip creating them. -{ - "v" : 1, - "unique" : true, - "key" : { - "username" : 1 - }, - "name" : "username_1", - "ns" : "parse.your_prefix:_User", - "background" : true, - "sparse" : true -} - -{ - "v" : 1, - "unique" : true, - "key" : { - "email" : 1 - }, - "name" : "email_1", - "ns" : "parse.your_prefix:_User", - "background" : true, - "sparse" : true -} - -// Create the username index. -// "background: true" is mandatory and avoids downtime while the index builds. -// "sparse: true" is also mandatory because Parse Server uses sparse indexes. -coll.ensureIndex({ username: 1 }, { background: true, unique: true, sparse: true }); - -// Create the email index. -// "background: true" is still mandatory. -// "sparse: true" is also mandatory both because Parse Server uses sparse indexes, and because email addresses are not required by the Parse API. -coll.ensureIndex({ email: 1 }, { background: true, unique: true, sparse: true }); -``` - -There are some issues you may run into during this process: - -## Mongo complains that the index already exists, but with different options - -In this case, you will need to remove the incorrect index. If your app relies on the existence of the index in order to be performant, you can create a new index, with "-1" for the direction of the field, so that it counts as different options. Then, drop the conflicting index, and create the unique index. - -## There is already non-unique data in the username or email field - -This is possible if you have explicitly set some user's emails to null. If this is bogus data, and those null fields should be unset, you can unset the null emails with this command. If your app relies on the difference between null and unset emails, you will need to upgrade your app to treat null and unset emails the same before building the index and upgrading to Parse Server 2.3.0. - -```js -coll.update({ email: { $exists: true, $eq: null } }, { $unset: { email: '' } }, { multi: true }) -``` - -## There is already non-unique data in the username or email field, and it's not nulls - -This is possible due to a race condition in previous versions of Parse Server. If you have this problem, it is unlikely that you have a lot of rows with duplicate data. We recommend you clean up the data manually, by removing or modifying the offending rows. - -This command, can be used to find the duplicate data: - -```js -coll.aggregate([ - {$match: {"username": {"$ne": null}}}, - {$group: {_id: "$username", uniqueIds: {$addToSet: "$_id"}, count: {$sum: 1}}}, - {$match: {count: {"$gt": 1}}}, - {$project: {id: "$uniqueIds", username: "$_id", _id : 0} }, - {$unwind: "$id" }, - {$out: '_duplicates'} // Save the list of duplicates to a new, "_duplicates" collection. Remove this line to just output the list. -], {allowDiskUse:true}) -``` diff --git a/3.0.0.md b/3.0.0.md deleted file mode 100644 index e34d2eeb9f..0000000000 --- a/3.0.0.md +++ /dev/null @@ -1,226 +0,0 @@ -# Upgrading Parse Server to version 3.0.0 - -parse-server 3.0.0 comes also with the JS SDK version 2.0 which requires a migration. Follow the migration guide [here](https://github.com/parse-community/Parse-SDK-JS/blob/master/2.0.0.md). - -With the 3.0.0, parse-server has completely revamped it's cloud code interface. Gone are the backbone style calls, welcome promises and async/await. - -In order to leverage those new nodejs features, you'll need to run at least node 8.10. We've dropped the support of node 6 a few months ago, so if you haven't made the change yet, now would be a really good time to take the plunge. - -## Migrating Cloud Code Hooks - -### Synchronous validations: - -```js -// before -Parse.Cloud.beforeSave('MyClassName', function(request, response) { - if (!passesValidation(request.object)) { - response.error('Ooops something went wrong'); - } else { - response.success(); - } -}); - -// after -Parse.Cloud.beforeSave('MyClassName', (request) => { - if (!passesValidation(request.object)) { - throw 'Ooops something went wrong'; - } -}); -``` - -All methods are wrapped in promises, so you can freely `throw` `Error`, `Parse.Error` or `string` to mark an error. - -### Asynchronous validations: - -For asynchronous code, you can use promises or async / await. - -Consider the following beforeSave call that would replace the contents of a fileURL with a proper copy of the image as a Parse.File. - -```js -// before -Parse.Cloud.beforeSave('Post', function(request, response) { - Parse.Cloud.httpRequest({ - url: request.object.get('fileURL'), - success: function(contents) { - const file = new Parse.File('image.png', { base64: contents.buffer.toString('base64') }); - file.save({ - success: function() { - request.object.set('file', file); - response.success(); - }, - error: response.error - }); - }, - error: response.error - }); -}); -``` - -As we can see the current way, with backbone style callbacks is quite tough to read and maintain. -It's also not really trivial to handle errors, as you need to pass the response.error to each error handlers. - -Now it can be modernized with promises: - -```js -// after (with promises) -Parse.Cloud.beforeSave('MyClassName', (request) => { - return Parse.Cloud.httpRequest({ - url: request.object.get('fileURL') - }).then((contents) => { - const file = new Parse.File('image.png', { base64: contents.buffer.toString('base64') }); - request.object.set('file', file); - return file.save(); - }); -}); -``` - -And you can even make it better with async/await. - -```js -// after with async/await -Parse.Cloud.beforeSave('MyClassName', async (request) => { - const contents = await Parse.Cloud.httpRequest({ - url: request.object.get('fileURL') - }); - - const file = new Parse.File('image.png', { base64: contents.buffer.toString('base64') }); - request.object.set('file', file); - await file.save(); -}); -``` - -## Aborting hooks and functions - -In order to abort a `beforeSave` or any hook, you now need to throw an error: - -```js -// after with async/await -Parse.Cloud.beforeSave('MyClassName', async (request) => { - // valid, will result in a Parse.Error(SCRIPT_FAILED, 'Something went wrong') - throw 'Something went wrong' - // also valid, will fail with Parse.Error(SCRIPT_FAILED, 'Something else went wrong') - throw new Error('Something else went wrong') - // using a Parse.Error is also valid - throw new Parse.Error(1001, 'My error') -}); -``` - -## Migrating Functions - -Cloud Functions can be migrated the same way as cloud code hooks. -In functions, the response object is not passed anymore, as it is in cloud code hooks - -Continuing with the image downloader example: - -```js -// before -Parse.Cloud.define('downloadImage', function(request, response) { - Parse.Cloud.httpRequest({ - url: request.params.url, - success: function(contents) { - const file = new Parse.File(request.params.name, { base64: contents.buffer.toString('base64') }); - file.save({ - success: function() { - response.success(file); - }, - error: response.error - }); - }, - error: response.error - }); -}); -``` - -You would call this method with: - -```js -Parse.Cloud.run('downloadImage',{ - url: 'https://example.com/file', - name: 'my-file' -}); -``` - -To migrate this function you would follow the same practices as the ones before, and we'll jump right away to the async/await implementation: - -```js -// after with async/await -Parse.Cloud.define('downloadImage', async (request) => { - const { - url, name - } = request.params; - const response = await Parse.Cloud.httpRequest({ url }); - - const file = new Parse.File(name, { base64: response.buffer.toString('base64') }); - await file.save(); - return file; -}); -``` - -## Migrating jobs - -As with hooks and functions, jobs don't have a status object anymore. -The message method has been moved to the request object. - -```js -// before -Parse.Cloud.job('downloadImageJob', function(request, status) { - var query = new Parse.Query('ImagesToDownload'); - query.find({ - success: function(images) { - var done = 0; - for (var i = 0; i { - request.message('Doing ' + image.get('url')); - const contents = await Parse.Cloud.httpRequest({ - url: image.get('url') - }); - request.message('Got ' + image.get('url')); - const file = new Parse.File(image.get('name'), { base64: contents.buffer.toString('base64') }); - await file.save(); - request.message('Saved ' + image.get('url')); - }); - await Promise.all(promises); -}); - -``` - -As you can see the new implementation is more concise, easier to read and maintain. - -If you encounter a problem or discover an issue with this guide, or with any Parse Community project, feel free to [reach out on github](https://github.com/parse-community/parse-server/issues/new/choose) - diff --git a/6.0.0.md b/6.0.0.md new file mode 100644 index 0000000000..780be79955 --- /dev/null +++ b/6.0.0.md @@ -0,0 +1,78 @@ +# Parse Server 6 Migration Guide + +This document only highlights specific changes that require a longer explanation. For a full list of changes in Parse Server 6 please refer to the [changelog](https://github.com/parse-community/parse-server/blob/alpha/CHANGELOG.md). + +--- + +- [Incompatible git protocol with Node 14](#incompatible-git-protocol-with-node-14) +- [Import Statement](#import-statement) +- [Asynchronous Initialization](#asynchronous-initialization) + +--- + +## Incompatible git protocol with Node 14 + +Parse Server 6 uses the Node Package Manger (npm) package lock file version 2. While version 2 is supposed to be backwards compatible with version 1, you may still encounter errors due to incompatible git protocols that cannot be interpreted correctly by npm bundled with Node 14. + +If you are encountering issues installing Parse Server on Node 14 because of dependency references in the package lock file using the `ssh` protocol, configure git to use the `https` protocol instead: + +``` +sudo git config --system url."https://github".insteadOf "ssh://git@github" +``` + +Alternatively you could manually replace the dependency URLs in the package lock file. + +⚠️ You could also delete the package lock file and recreate it with Node 14. Keep in mind that doing so you are not using an official version of Parse Server anymore. You may be using dependencies that have not been tested as part of the Parse Server release process. + +## Import Statement + +The import and initialization syntax has been simplified with more intuitive naming and structure. + +*Parse Server 5:* +```js +// Returns a Parse Server instance +const ParseServer = require('parse-server'); + +// Returns a Parse Server express middleware +const { ParseServer } = require('parse-server'); +``` + +*Parse Server 6:* +```js +// Both return a Parse Server instance +const ParseServer = require('parse-server'); +const { ParseServer } = require('parse-server'); +``` + +To get the express middleware in Parse Server 6, configure the Parse Server instance, start Parse Server and use its `app` property. See [Asynchronous Initialization](#asynchronous-initialization) for more details. + +## Asynchronous Initialization + +Previously, it was possible to mount Parse Server before it was fully started up and ready to receive requests. This could result in undefined behavior, such as Parse Objects could be saved before Cloud Code was registered. To prevent this, Parse Server 6 requires to be started asynchronously before being mounted. + +*Parse Server 5:* +```js +// 1. Import Parse Server +const { ParseServer } = require('parse-server'); + +// 2. Create a Parse Server instance as express middleware +const server = new ParseServer(config); + +// 3. Mount express middleware +app.use("/parse", server); +``` + +*Parse Server 6:* +```js +// 1. Import Parse Server +const ParseServer = require('parse-server'); + +// 2. Create a Parse Server instance +const server = new ParseServer(config); + +// 3. Start up Parse Server asynchronously +await server.start(); + +// 4. Mount express middleware +app.use("/parse", server.app); +``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ee058a685d..270b66e385 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,7 @@ ## Table of Contents - [Contributing](#contributing) - [Issue vs. Pull Request](#issue-vs-pull-request) + - [Scope](#scope) - [Templates](#templates) - [Why Contributing?](#why-contributing) - [Contribution FAQs](#contribution-faqs) @@ -10,6 +11,10 @@ - [Review Feedback](#review-feedback) - [Merge Readiness](#merge-readiness) - [Review Validity](#review-validity) + - [Code Ownership](#code-ownership) + - [Access Permissions](#access-permissions) + - [New Private Repository](#new-private-repository) + - [New Public Repository](#new-public-repository) - [Environment Setup](#environment-setup) - [Recommended Tools](#recommended-tools) - [Setting up your local machine](#setting-up-your-local-machine) @@ -32,6 +37,9 @@ - [Merging](#merging) - [Breaking Change](#breaking-change-1) - [Reverting](#reverting) + - [Security Vulnerability](#security-vulnerability) + - [Local Testing](#local-testing) + - [Merging](#merging-1) - [Releasing](#releasing) - [General Considerations](#general-considerations) - [Major Release / Long-Term-Support](#major-release--long-term-support) @@ -64,6 +72,14 @@ An issue is required to be linked in every pull request. We understand that no-o - The discussion in the issue is different from the discussion in the pull request. The issue discussion is focused on the issue and how to address it, whereas the discussion in the pull request is focused on a specific implemention. An issue may even have multiple pull requests because either the issue requires multiple implementations or multiple pull requests are opened to compare and test different approaches to later decide for one. - High-level conceptual discussions about the issue should be still available, even if a pull request is closed because its appraoch was discarded. If these discussions are in the pull request instead, they can easily become fragmented over multiple pull requests and issues, which can make it very hard to make sense of all aspects of an issue. +### Scope + +An issue and pull request must limit its scope on a distinct issue. Pull requests can only contain changes that are required to address the scoped issue. While it may seem quick and easy to add unrelated changes to the pull request, it can cause singificant complications after merging. Some of the reasons are: + +- A pull request corresponds to a single changelog entry. A changelog entry should not describe multiple unrelated changes in one entry for better readability. +- A pull request creates a distinct commit; having an individual commit for each limited scope makes it easier for others to go back in the commit history and debug. Bugs are generally more difficult to identify and fix if there are various unrelated changes merged at once. +- If a pull request needs to be reverted, unrelated changes will be reverted as well. That makes it more complex and time consuming to revert, having to consider its effects and possibly publishing a broken release or requiring a follow-up pull request with code manipulation. + ### Templates You are required to use and completely fill out the templates for new issues and pull requests. We understand that no-one enjoys filling out forms, but here is why this is beneficial for everyone: @@ -133,6 +149,30 @@ It's contrary to an open, collaborative environment to expect others to be invol Your arguments must focus on the issue, not on your assumption of someone else's personal experience. We will take immediate and appropriate action in case of personal attacks, regardless of your previous contributions. Personal attacks are not permissible. If you became a victim of personal attacks, you can privately [report](https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam) the GitHub comment to the Parse Platform PMC. +### Code Ownership + +> *Can I open a new pull request based on another author's pull request?* + +If your pull request contains work from someone else then you are required to get their permission to use their work in your pull request. Please make sure to observe the [license](LICENSE) for more details. In addition, as an appreciative gesture you should clearly mention that your pull request is based on another pull request with a link in the top-most comment of your pull request. To avoid this issue we encourage contributors to collaborate on a single pull request to preserve the commit history and clearly identify each author's contribution. To do so, you can review the other author's pull request and submit your code suggestions, or ask the original author to grant you write access to their repository to also be able to make commits directly to their pull request. + +### Access Permissions + +> *Can I get write access to the repository to make changes faster?* + +Keeping our products safe and secure is one of your top priorities. Our security policy mandates that write access to repositories is only provided to as few people as necessary. All usual contributions can be made via public pull requests. If you think you need write access, contact the repository team and explain in detail what the constraint is that you are trying to overcome. We want to make contributing for you as easy as possible. If there are any bottlenecks that are slowing you down we are happy to receive your feedback to see where we can improve. + +### New Private Repository + +> *Can I get a new private repository within the Parse Platform organization to work on some stuff?* + +Private repositories are not provided unless there is a significant constraint or requirement that makes it necessary. For example, when collaborating on fixing a security vulnerability we provide private repositories to allow collaborators to share sensitive information within a select group. + +### New Public Repository + +> *Can I get a new public repository within the Parse Platform organization to work on some stuff?* + +First of all, we appreciate your contribution. In rare cases, where we consider it beneficial to the advancement of the repository, a new public repository for a specific purpose may be provided, for example for increased visibility or to provide the organization's GitHub ressources. In other cases, we encourage you to start your contribution in a personal repository of your own GitHub account, and later transfer it to the Parse Platform organization. We will be happy to assist you in the repository transfer. + ## Environment Setup ### Recommended Tools @@ -202,7 +242,11 @@ Once you have babel running in watch mode, you can start making changes to parse If your pull request introduces a change that may affect the storage or retrieval of objects, you may want to make sure it plays nice with Postgres. -* Run the tests against the postgres database with `PARSE_SERVER_TEST_DB=postgres PARSE_SERVER_TEST_DATABASE_URI=postgres://postgres:password@localhost:5432/parse_server_postgres_adapter_test_database npm run testonly`. You'll need to have postgres running on your machine and setup [appropriately](https://github.com/parse-community/parse-server/blob/master/scripts/before_script_postgres.sh) or use [`Docker`](#run-a-parse-postgres-with-docker). +* You'll need to have postgres running on your machine and setup [appropriately](https://github.com/parse-community/parse-server/blob/master/scripts/before_script_postgres.sh) or use [`Docker`](#postgres-with-docker) +* Run the tests against the postgres database with: + ``` + PARSE_SERVER_TEST_DB=postgres PARSE_SERVER_TEST_DATABASE_URI=postgres://postgres:password@localhost:5432/parse_server_postgres_adapter_test_database npm run testonly + ``` * The Postgres adapter has a special debugger that traces all the sql commands. You can enable it with setting the environment variable `PARSE_SERVER_LOG_LEVEL=debug` * If your feature is intended to only work with MongoDB, you should disable PostgreSQL-specific tests with: @@ -224,10 +268,10 @@ If your pull request introduces a change that may affect the storage or retrieva #### Postgres with Docker -[PostGIS images (select one with v2.2 or higher) on docker dashboard](https://hub.docker.com/r/postgis/postgis) is based off of the official [postgres](https://registry.hub.docker.com/_/postgres/) image and will work out-of-the-box (as long as you create a user with the necessary extensions for each of your Parse databases; see below). To launch the compatible Postgres instance, copy and paste the following line into your shell: +[PostGIS images (select one with v2.2 or higher) on docker hub](https://hub.docker.com/r/postgis/postgis) is based off of the official [postgres](https://hub.docker.com/_/postgres) image and will work out-of-the-box (as long as you create a user with the necessary extensions for each of your Parse databases; see below). To launch the compatible Postgres instance, copy and paste the following line into your shell: ``` -docker run -d --name parse-postgres -p 5432:5432 -e POSTGRES_PASSWORD=password --rm postgis/postgis:13-3.2-alpine && sleep 20 && docker exec -it parse-postgres psql -U postgres -c 'CREATE DATABASE parse_server_postgres_adapter_test_database;' && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION pgcrypto; CREATE EXTENSION postgis;' -d parse_server_postgres_adapter_test_database && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION postgis_topology;' -d parse_server_postgres_adapter_test_database +docker run -d --name parse-postgres -p 5432:5432 -e POSTGRES_PASSWORD=password --rm postgis/postgis:16-3.4-alpine && sleep 20 && docker exec -it parse-postgres psql -U postgres -c 'CREATE DATABASE parse_server_postgres_adapter_test_database;' && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION pgcrypto; CREATE EXTENSION postgis;' -d parse_server_postgres_adapter_test_database && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION postgis_topology;' -d parse_server_postgres_adapter_test_database ``` To stop the Postgres instance: @@ -235,7 +279,7 @@ To stop the Postgres instance: docker stop parse-postgres ``` -You can also use the [postgis/postgis:13-3.2-alpine](https://hub.docker.com/r/postgis/postgis) image in a Dockerfile and copy this [script](https://github.com/parse-community/parse-server/blob/master/scripts/before_script_postgres.sh) to the image by adding the following lines: +You can also use the [postgis/postgis:16-3.4-alpine](https://hub.docker.com/r/postgis/postgis) image in a Dockerfile and copy this [script](https://github.com/parse-community/parse-server/blob/master/scripts/before_script_postgres.sh) to the image by adding the following lines: ``` #Install additional scripts. These are run in abc order during initial start @@ -451,6 +495,24 @@ If the commit reverts a previous commit, use the prefix `revert:`, followed by t This reverts commit 1234567890abcdef. ``` +### Security Vulnerability + +#### Local Testing + +Fixes for securify vulnerabilities are developed in private forks with a closed audience, inaccessible to the public. A current GitHub limitation does not allow to run CI tests on pull requests in private forks. Whether a pull requests fully passes all CI tests can only be determined by publishing the fix as a public pull request and running the CI. This means the fix and implicitly information about the vulnerabilty are made accessible to the public. This increases the risk that a vulnerability fix is published, but then cannot be merged immediately due to a CI issue. To mitigate that risk, before publishing a vulnerability fix, the following tests needs to be run locally and pass: + +- `npm run test` (MongoDB) +- `npm run test` (Postgres) +- `npm run madge:circular` (circular dependencies) +- `npm run lint` (Lint) +- `npm run definitions` (Parse Server options definitions) + +#### Merging + +A current GitHub limitation does not allow to customize the commit message when merging pull requests of a private fork that was created to fix a security vulnerabilty. Our release automation framework demands a specific commit message syntax which therefore cannot be met. This prohibits to follow the process that GitHub suggest, which is to merge a pull request from a private fork directly to a public branch. Instead, after [local testing](#local-testing), a public pull request needs to be created with the code fix copied over from the private pull request. + +This creates a risk that a vulnerability is indirectly disclosed by publishing a pull request with the fix, but the fix cannot be merged due to a CI issue. To mitigate that risk, the pull request title and description should be kept marginal or generic, not hiting to a vulnerabilty or giving any details about the vulnerabilty, until the pull request has been successfully merged. + ## Releasing ### General Considerations @@ -468,7 +530,6 @@ The following changes are done in the `alpha` branch, before publishing the last - Make sure all [deprecations](https://github.com/parse-community/parse-server/blob/alpha/DEPRECATIONS.md) are reflected in code, old code is removed and the deprecations table is updated. - Add the future LTS branch `release-#.x.x` to the branch list in [release.config.js](https://github.com/parse-community/parse-server/blob/alpha/release.config.js) so that the branch will later be recognized for release automation. - ### Publishing Release (forward-merge): 1. Create new temporary branch `build` on branch `beta`. @@ -519,6 +580,7 @@ The following changes are done in the `alpha` branch, before publishing the last 1. Create LTS branch `release-#.x.x` off the latest version tag on `release` branch. 2. Create temporary branch `build-release` off branch `beta` and create a pull request with `release` as the base branch. 3. Merge branch `build-release` into `release`. Given that there will be breaking changes, a new major release will be created. In the unlikely case that there have been no breaking changes between the previous major release and the upcoming release, a major version increment has to be triggered manually. See the docs of the release automation framework for how to do that. +4. Add newly created LTS branch `release-#.x.x` from step 1 to [Snyk](https://snyk.io) so that Snyk opens pull requests for the LTS branch; remove previously existing LTS branch `release-#.x.x` from Snyk. ## Versioning diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index 82aa8144a0..af683c2d46 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -4,13 +4,16 @@ The following is a list of deprecations, according to the [Deprecation Policy](h | ID | Change | Issue | Deprecation [ℹ️][i_deprecation] | Planned Removal [ℹ️][i_removal] | Status [ℹ️][i_status] | Notes | |--------|-------------------------------------------------|----------------------------------------------------------------------|---------------------------------|---------------------------------|-----------------------|-------| -| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | -| DEPPS2 | Config option `directAccess` defaults to `true` | [#6636](https://github.com/parse-community/parse-server/pull/6636) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | -| DEPPS3 | Config option `enforcePrivateUsers` defaults to `true` | [#7319](https://github.com/parse-community/parse-server/pull/7319) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | -| DEPPS4 | Remove convenience method for http request `Parse.Cloud.httpRequest` | [#7589](https://github.com/parse-community/parse-server/pull/7589) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | -| DEPPS5 | Config option `allowClientClassCreation` defaults to `false` | [#7925](https://github.com/parse-community/parse-server/pull/7925) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - | -| DEPPS6 | Auth providers disabled by default | [#7953](https://github.com/parse-community/parse-server/pull/7953) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - | -| DEPPS7 | Remove file trigger syntax `Parse.Cloud.beforeSaveFile((request) => {})` | [#7966](https://github.com/parse-community/parse-server/pull/7966) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - | +| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - | +| DEPPS2 | Config option `directAccess` defaults to `true` | [#6636](https://github.com/parse-community/parse-server/pull/6636) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - | +| DEPPS3 | Config option `enforcePrivateUsers` defaults to `true` | [#7319](https://github.com/parse-community/parse-server/pull/7319) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - | +| DEPPS4 | Remove convenience method for http request `Parse.Cloud.httpRequest` | [#7589](https://github.com/parse-community/parse-server/pull/7589) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - | +| DEPPS5 | Config option `allowClientClassCreation` defaults to `false` | [#7925](https://github.com/parse-community/parse-server/pull/7925) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - | +| DEPPS6 | Auth providers disabled by default | [#7953](https://github.com/parse-community/parse-server/pull/7953) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - | +| DEPPS7 | Remove file trigger syntax `Parse.Cloud.beforeSaveFile((request) => {})` | [#7966](https://github.com/parse-community/parse-server/pull/7966) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - | +| DEPPS8 | Login with expired 3rd party authentication token defaults to `false` | [#7079](https://github.com/parse-community/parse-server/pull/7079) | 5.3.0 (2022) | 7.0.0 (2024) | removed | - | +| DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | removed | - | +| DEPPS10 | Config option `encodeParseObjectInCloudFunction` defaults to `true` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 8.0.0 (2025) | deprecated | - | [i_deprecation]: ## "The version and date of the deprecation." [i_removal]: ## "The version and date of the planned removal." diff --git a/LICENSE b/LICENSE index f11b38ba73..4877592850 100644 --- a/LICENSE +++ b/LICENSE @@ -1,34 +1,176 @@ -BSD License + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -For Parse Server software +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Copyright (c) 2015-present, Parse, LLC. All rights reserved. +1. Definitions. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. - * Neither the name Parse nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. ------ + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. -As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code. + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000000..ef5ddb2201 --- /dev/null +++ b/NOTICE @@ -0,0 +1,10 @@ +Parse Server + +Copyright 2015-present Parse Platform + +This product includes software developed at Parse Platform. +www.parseplatform.org + +--- + +As of April 5, 2017, Parse, LLC has transferred this code to the Parse Platform organization, and will no longer be contributing to or distributing this code. diff --git a/PATENTS b/PATENTS deleted file mode 100644 index a6dc00000d..0000000000 --- a/PATENTS +++ /dev/null @@ -1,37 +0,0 @@ -Additional Grant of Patent Rights Version 2 - -"Software" means the Parse Server software distributed by Parse, LLC. - -Parse, LLC. ("Parse") hereby grants to each recipient of the Software -("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable -(subject to the termination provision below) license under any Necessary -Claims, to make, have made, use, sell, offer to sell, import, and otherwise -transfer the Software. For avoidance of doubt, no license is granted under -Parse’s rights in any patent claims that are infringed by (i) modifications -to the Software made by you or any third party or (ii) the Software in -combination with any software or other technology. - -The license granted hereunder will terminate, automatically and without notice, -if you (or any of your subsidiaries, corporate affiliates or agents) initiate -directly or indirectly, or take a direct financial interest in, any Patent -Assertion: (i) against Parse or any of its subsidiaries or corporate -affiliates, (ii) against any party if such Patent Assertion arises in whole or -in part from any software, technology, product or service of Parse or any of -its subsidiaries or corporate affiliates, or (iii) against any party relating -to the Software. Notwithstanding the foregoing, if Parse or any of its -subsidiaries or corporate affiliates files a lawsuit alleging patent -infringement against you in the first instance, and you respond by filing a -patent infringement counterclaim in that lawsuit against that party that is -unrelated to the Software, the license granted hereunder will not terminate -under section (i) of this paragraph due to such counterclaim. - -A "Necessary Claim" is a claim of a patent owned by Parse that is -necessarily infringed by the Software standing alone. - -A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, -or contributory infringement or inducement to infringe any patent, including a -cross-claim or counterclaim. - ------ - -As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code. diff --git a/README.md b/README.md index 9a6ee007d9..fa99c2f9bc 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,17 @@ ![parse-repository-header-server](https://user-images.githubusercontent.com/5673677/138278489-7d0cebc5-1e31-4d3c-8ffb-53efcda6f29d.png) --- - + [![Build Status](https://github.com/parse-community/parse-server/workflows/ci/badge.svg?branch=alpha)](https://github.com/parse-community/parse-server/actions?query=workflow%3Aci+branch%3Aalpha) +[![Build Status](https://github.com/parse-community/parse-server/workflows/ci/badge.svg?branch=beta)](https://github.com/parse-community/parse-server/actions?query=workflow%3Aci+branch%3Abeta) +[![Build Status](https://github.com/parse-community/parse-server/workflows/ci/badge.svg?branch=release)](https://github.com/parse-community/parse-server/actions?query=workflow%3Aci+branch%3Arelease) [![Snyk Badge](https://snyk.io/test/github/parse-community/parse-server/badge.svg)](https://snyk.io/test/github/parse-community/parse-server) [![Coverage](https://img.shields.io/codecov/c/github/parse-community/parse-server/alpha.svg)](https://codecov.io/github/parse-community/parse-server?branch=alpha) [![auto-release](https://img.shields.io/badge/%F0%9F%9A%80-auto--release-9e34eb.svg)](https://github.com/parse-community/parse-dashboard/releases) -[![Node Version](https://img.shields.io/badge/nodejs-12,_14,_16,_17,_18-green.svg?logo=node.js&style=flat)](https://nodejs.org) +[![Node Version](https://img.shields.io/badge/nodejs-18,_20-green.svg?logo=node.js&style=flat)](https://nodejs.org) [![MongoDB Version](https://img.shields.io/badge/mongodb-4.0,_4.2,_4.4,_5,_6-green.svg?logo=mongodb&style=flat)](https://www.mongodb.com) -[![Postgres Version](https://img.shields.io/badge/postgresql-11,_12,_13,_14,_15-green.svg?logo=postgresql&style=flat)](https://www.postgresql.org) +[![Postgres Version](https://img.shields.io/badge/postgresql-13,_14,_15,_16-green.svg?logo=postgresql&style=flat)](https://www.postgresql.org) [![npm latest version](https://img.shields.io/npm/v/parse-server/latest.svg)](https://www.npmjs.com/package/parse-server) [![npm beta version](https://img.shields.io/npm/v/parse-server/beta.svg)](https://www.npmjs.com/package/parse-server) @@ -17,7 +19,6 @@ [![Backers on Open Collective](https://opencollective.com/parse-server/backers/badge.svg)][open-collective-link] [![Sponsors on Open Collective](https://opencollective.com/parse-server/sponsors/badge.svg)][open-collective-link] -[![License][license-svg]][license-link] [![Forum](https://img.shields.io/discourse/https/community.parseplatform.org/topics.svg)](https://community.parseplatform.org/c/parse-server) [![Twitter](https://img.shields.io/twitter/follow/ParsePlatform.svg?label=Follow&style=social)](https://twitter.com/intent/follow?screen_name=ParsePlatform) [![Chat](https://img.shields.io/badge/Chat-Join!-%23fff?style=social&logo=slack)](https://chat.parseplatform.org) @@ -38,7 +39,7 @@ A big *thank you* 🙏 to our [sponsors](#sponsors) and [backers](#backers) who --- -- [Flavors & Branches](#flavors--branches) +- [Flavors \& Branches](#flavors--branches) - [Long Term Support](#long-term-support) - [Getting Started](#getting-started) - [Running Parse Server](#running-parse-server) @@ -53,9 +54,12 @@ A big *thank you* 🙏 to our [sponsors](#sponsors) and [backers](#backers) who - [Running Parse Server elsewhere](#running-parse-server-elsewhere) - [Sample Application](#sample-application) - [Parse Server + Express](#parse-server--express) + - [Parse Server Health](#parse-server-health) + - [Status Values](#status-values) - [Configuration](#configuration) - [Basic Options](#basic-options) - [Client Key Options](#client-key-options) + - [Access Scopes](#access-scopes) - [Email Verification and Password Reset](#email-verification-and-password-reset) - [Password and Account Policy](#password-and-account-policy) - [Custom Routes](#custom-routes) @@ -87,7 +91,6 @@ A big *thank you* 🙏 to our [sponsors](#sponsors) and [backers](#backers) who - [Using automatically generated operations](#using-automatically-generated-operations) - [Customizing your GraphQL Schema](#customizing-your-graphql-schema) - [Learning more](#learning-more) -- [Upgrading to Parse Server 3.0](#upgrading-to-parse-server-30) - [Contributing](#contributing) - [Contributors](#contributors) - [Sponsors](#sponsors) @@ -98,13 +101,13 @@ A big *thank you* 🙏 to our [sponsors](#sponsors) and [backers](#backers) who Parse Server is available in different flavors on different branches: - The main branches are [release][log_release], [beta][log_beta] and [alpha][log_alpha]. See the [changelog overview](CHANGELOG.md) for details. -- The long-term-support (LTS) branches are named `release-.x.x`, for example `release-4.x.x`. LTS branches do not have pre-release branches. +- The long-term-support (LTS) branches are named `release-.x.x`, for example `release-5.x.x`. LTS branches do not have pre-release branches. ## Long Term Support -Long-Term-Support (LTS) is provided for the previous Parse Server major version. For example, Parse Server 4.x will receive security updates until Parse Server 5.x is superseded by Parse Server 6.x and becomes the new LTS version. While the current major version is published on branch `release`, a LTS version is published on branch `release-#.x.x`, for example `release-4.x.x` for the Parse Server 4.x LTS branch. +Long-Term-Support (LTS) is provided for the previous Parse Server major version. For example, Parse Server 5.x will receive security updates until Parse Server 6.x is superseded by Parse Server 7.x and becomes the new LTS version. While the current major version is published on branch `release`, a LTS version is published on branch `release-#.x.x`, for example `release-5.x.x` for the Parse Server 5.x LTS branch. -⚠️ LTS versions are provided to help you transition as soon as possible to the current major version. While we aim to fix security vulnerabilities in the LTS version, our main focus is on developing the current major version and preparing the next major release. Therefore we may leave certain vulnerabilities up to the community to fix. Search for [pull requests with the specific LTS base branch](https://github.com/parse-community/parse-server/pulls?q=is%3Aopen+is%3Apr+base%3Arelease-4.x.x) to see the current open vulnerabilities for that LTS branch. +⚠️ LTS versions are provided to help you transition as soon as possible to the current major version. While we aim to fix security vulnerabilities in the LTS version, our main focus is on developing the current major version and preparing the next major release. Therefore we may leave certain vulnerabilities up to the community to fix. Search for [pull requests with the specific LTS base branch](https://github.com/parse-community/parse-server/pulls?q=is%3Aopen+is%3Apr+base%3Arelease-5.x.x) to see the current open vulnerabilities for that LTS branch. # Getting Started @@ -126,23 +129,21 @@ Parse Server is continuously tested with the most recent releases of Node.js to | Version | Latest Version | End-of-Life | Compatible | |------------|----------------|-------------|------------| -| Node.js 12 | 12.22.11 | April 2022 | ✅ Yes | -| Node.js 14 | 14.19.1 | April 2023 | ✅ Yes | -| Node.js 16 | 16.14.2 | April 2024 | ✅ Yes | -| Node.js 17 | 17.9.0 | June 2022 | ✅ Yes | -| Node.js 18 | 18.1.0 | April 2025 | ✅ Yes | +| Node.js 18 | 18.19.1 | April 2025 | ✅ Yes | +| Node.js 20 | 20.11.1 | April 2026 | ✅ Yes | #### MongoDB Parse Server is continuously tested with the most recent releases of MongoDB to ensure compatibility. We follow the [MongoDB support schedule](https://www.mongodb.com/support-policy) and [MongoDB lifecycle schedule](https://www.mongodb.com/support-policy/lifecycles) and only test against versions that are officially supported and have not reached their end-of-life date. We consider the end-of-life date of a MongoDB "rapid release" to be the same as its major version release. -| Version | Latest Version | End-of-Life | Compatible | -|-------------|----------------|---------------|--------------| -| MongoDB 4.0 | 4.0.28 | April 2022 | ✅ Yes | -| MongoDB 4.2 | 4.2.19 | April 2023 | ✅ Yes | -| MongoDB 4.4 | 4.4.13 | February 2024 | ✅ Yes | -| MongoDB 5 | 5.3.2 | October 2024 | ✅ Yes | -| MongoDB 6 | 6.0.2 | July 2025 | ✅ Yes | +| Version | Latest Version | End-of-Life | Compatible | +| ----------- | -------------- | ------------- | ---------- | +| MongoDB 4.0 | 4.0.28 | April 2022 | ✅ Yes | +| MongoDB 4.2 | 4.2.19 | April 2023 | ✅ Yes | +| MongoDB 4.4 | 4.4.13 | February 2024 | ✅ Yes | +| MongoDB 5 | 5.3.2 | October 2024 | ✅ Yes | +| MongoDB 6 | 6.0.2 | July 2025 | ✅ Yes | +| MongoDB 7 | 7.0.1 | TDB | ✅ Yes | #### PostgreSQL @@ -150,11 +151,10 @@ Parse Server is continuously tested with the most recent releases of PostgreSQL | Version | PostGIS Version | End-of-Life | Parse Server Support | Compatible | |-------------|--------------------|---------------|----------------------|------------| -| Postgres 11 | 3.0, 3.1, 3.2, 3.3 | November 2023 | <= 5.x (2022) | ✅ Yes | -| Postgres 12 | 3.3 | November 2024 | <= 5.x (2022) | ✅ Yes | -| Postgres 13 | 3.3 | November 2025 | <= 6.x (2023) | ✅ Yes | -| Postgres 14 | 3.3 | November 2026 | <= 7.x (2024) | ✅ Yes | -| Postgres 15 | 3.3 | November 2027 | <= 8.x (2025) | ✅ Yes | +| Postgres 13 | 3.1, 3.2, 3.3, 3.4 | November 2025 | <= 6.x (2023) | ✅ Yes | +| Postgres 14 | 3.4 | November 2026 | <= 7.x (2024) | ✅ Yes | +| Postgres 15 | 3.4 | November 2027 | <= 8.x (2025) | ✅ Yes | +| Postgres 16 | 3.4 | November 2028 | <= 9.x (2026) | ✅ Yes | ### Locally @@ -282,11 +282,11 @@ We have provided a basic [Node.js application](https://github.com/parse-communit You can also create an instance of Parse Server, and mount it on a new or existing Express website: ```js -var express = require('express'); -var ParseServer = require('parse-server').ParseServer; -var app = express(); +const express = require('express'); +const ParseServer = require('parse-server').ParseServer; +const app = express(); -var api = new ParseServer({ +const server = new ParseServer({ databaseURI: 'mongodb://localhost:27017/dev', // Connection string for your MongoDB database cloud: './cloud/main.js', // Path to your Cloud Code appId: 'myAppId', @@ -295,8 +295,11 @@ var api = new ParseServer({ serverURL: 'http://localhost:1337/parse' // Don't forget to change to https if needed }); +// Start server +await server.start(); + // Serve the Parse API on the /parse URL prefix -app.use('/parse', api); +app.use('/parse', server.app); app.listen(1337, function() { console.log('parse-server-example running on port 1337.'); @@ -305,6 +308,27 @@ app.listen(1337, function() { For a full list of available options, run `parse-server --help` or take a look at [Parse Server Configurations](http://parseplatform.org/parse-server/api/master/ParseServerOptions.html). +## Parse Server Health + +Check the Parse Server health by sending a request to the `/parse/health` endpoint. + +The response looks like this: + +```json +{ + "status": "ok" +} +``` + +### Status Values + +| Value | Description | +|---------------|-----------------------------------------------------------------------------| +| `initialized` | The server has been created but the `start` method has not been called yet. | +| `starting` | The server is starting up. | +| `ok` | The server started and is running. | +| `error` | There was a startup error, see the logs for details. | + # Configuration Parse Server can be configured using the following options. You may pass these as parameters when running a standalone `parse-server`, or by loading a configuration file in JSON format using `parse-server path/to/configuration.json`. If you're using Parse Server on Express, you may also pass these to the `ParseServer` object as options. @@ -330,6 +354,17 @@ The client keys used with Parse are no longer necessary with Parse Server. If yo * `restAPIKey` * `dotNetKey` +## Access Scopes + +| Scope | Internal data | Read-only data (1) | Custom data | Restricted by CLP, ACL | Key | +|----------------|---------------|-------------------------------|-------------|------------------------|---------------------| +| Internal | r/w | r/w | r/w | no | `maintenanceKey` | +| Master | -/- | r/- | r/w | no | `masterKey` | +| ReadOnlyMaster | -/- | r/- | r/- | no | `readOnlyMasterKey` | +| Session | -/- | r/- | r/w | yes | `sessionToken` | + +(1) `Parse.Object.createdAt`, `Parse.Object.updatedAt`. + ## Email Verification and Password Reset Verifying user email addresses and enabling password reset via email requires an email adapter. There are many email adapters provided and maintained by the community. The following is an example configuration with an example email adapter. See the [Parse Server Options](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html) for more details and a full list of available options. @@ -389,7 +424,7 @@ const server = ParseServer({ }, // The password policy - passwordPolicy: { + passwordPolicy: { // Enforce a password of at least 8 characters which contain at least 1 lower case, 1 upper case and 1 digit validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/, // Do not allow the username as part of the password @@ -430,7 +465,7 @@ const api = new ParseServer({ The above route can be invoked by sending a `GET` request to: `https://[parseServerPublicUrl]/[parseMount]/[pagesEndpoint]/[appId]/[customRoute]` - + The `handler` receives the `request` and returns a `custom_page.html` webpage from the `pages.pagesPath` directory as response. The advantage of building a custom route this way is that it automatically makes use of Parse Server's built-in capabilities, such as [page localization](#pages) and [dynamic placeholders](#dynamic-placeholders). ### Reserved Paths @@ -461,7 +496,7 @@ The following paths are already used by Parse Server's built-in features and are It’s possible to change the default pages of the app and redirect the user to another path or domain. ```js -var server = ParseServer({ +const server = ParseServer({ ...otherOptions, customPages: { @@ -518,7 +553,7 @@ Parse Server allows developers to choose from several options when hosting files `GridFSBucketAdapter` is used by default and requires no setup, but if you're interested in using Amazon S3, Google Cloud Storage, or local file storage, additional configuration information is available in the [Parse Server guide](http://docs.parseplatform.org/parse-server/guide/#configuring-file-adapters). ## Idempotency Enforcement - + **Caution, this is an experimental feature that may not be appropriate for production.** This feature deduplicates identical requests that are received by Parse Server multiple times, typically due to network issues or network adapter access restrictions on mobile operating systems. @@ -851,7 +886,7 @@ Then, create an `index.js` file with the following content: ```js const express = require('express'); -const { default: ParseServer, ParseGraphQLServer } = require('parse-server'); +const { ParseServer, ParseGraphQLServer } = require('parse-server'); const app = express(); @@ -875,6 +910,7 @@ app.use('/parse', parseServer.app); // (Optional) Mounts the REST API parseGraphQLServer.applyGraphQL(app); // Mounts the GraphQL API parseGraphQLServer.applyPlayground(app); // (Optional) Mounts the GraphQL Playground - do NOT use in Production +await parseServer.start(); app.listen(1337, function() { console.log('REST API running on http://localhost:1337/parse'); console.log('GraphQL API running on http://localhost:1337/graphql'); @@ -1116,12 +1152,6 @@ You also have a very powerful tool inside your GraphQL Playground. Please look a Additionally, the [GraphQL Learn Section](https://graphql.org/learn/) is a very good source to learn more about the power of the GraphQL language. -# Upgrading to Parse Server 3.0 - -Starting Parse Server 3.0, Parse Server uses the Parse JavaScript SDK 2.0. In short, the Parse JavaScript SDK 2.0 removes the backbone style callbacks as well as the `Parse.Promise` object in favor of native promises. All the Cloud Code interfaces also have been updated to reflect those changes, and all backbone style response objects are removed and replaced by promise style resolution. - -We have written up a [migration guide](3.0.0.md) to help you transition to the next major release. - # Contributing Please see the [Contributing Guide](CONTRIBUTING.md). @@ -1173,12 +1203,6 @@ Support us with a monthly donation and help us continue our activities. [Become ------ - -As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code. - -[license-svg]: https://img.shields.io/badge/license-BSD-lightgrey.svg -[license-link]: LICENSE [open-collective-link]: https://opencollective.com/parse-server [log_release]: https://github.com/parse-community/parse-server/blob/release/changelogs/CHANGELOG_release.md [log_beta]: https://github.com/parse-community/parse-server/blob/beta/changelogs/CHANGELOG_beta.md diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index b864e3181b..59e5736f90 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,939 @@ +# [7.0.0-alpha.29](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.28...7.0.0-alpha.29) (2024-03-19) + + +### Bug Fixes + +* Server crashes on invalid Cloud Function or Cloud Job name; fixes security vulnerability [GHSA-6hh7-46r2-vf29](https://github.com/parse-community/parse-server/security/advisories/GHSA-6hh7-46r2-vf29) ([#9024](https://github.com/parse-community/parse-server/issues/9024)) ([9f6e342](https://github.com/parse-community/parse-server/commit/9f6e3429d3b326cf4e2994733c618d08032fac6e)) + +# [7.0.0-alpha.28](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.27...7.0.0-alpha.28) (2024-03-17) + + +### Features + +* Upgrade to Parse JS SDK 5 ([#9022](https://github.com/parse-community/parse-server/issues/9022)) ([ad4aa83](https://github.com/parse-community/parse-server/commit/ad4aa83983205a0e27639f6ee6a4a5963b67e4b8)) + +# [7.0.0-alpha.27](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.26...7.0.0-alpha.27) (2024-03-15) + + +### Bug Fixes + +* CacheAdapter does not connect when using a CacheAdapter with a JSON config ([#8633](https://github.com/parse-community/parse-server/issues/8633)) ([720d24e](https://github.com/parse-community/parse-server/commit/720d24e18540da35d50957f17be878316ec30318)) + +# [7.0.0-alpha.26](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.25...7.0.0-alpha.26) (2024-03-10) + + +### Bug Fixes + +* Parse Server option `fileExtensions` default value rejects file extensions that are less than 3 or more than 4 characters long ([#8699](https://github.com/parse-community/parse-server/issues/8699)) ([2760381](https://github.com/parse-community/parse-server/commit/276038118377c2b22381bcd8d30337203822121b)) + +# [7.0.0-alpha.25](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.24...7.0.0-alpha.25) (2024-03-05) + + +### Features + +* Deprecation DEPPS5: Config option `allowClientClassCreation` defaults to `false` ([#8849](https://github.com/parse-community/parse-server/issues/8849)) ([29624e0](https://github.com/parse-community/parse-server/commit/29624e0fae17161cd412ae58d35a195cfa286cad)) + + +### BREAKING CHANGES + +* The Parse Server option `allowClientClassCreation` defaults to `false`. ([29624e0](29624e0)) + +# [7.0.0-alpha.24](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.23...7.0.0-alpha.24) (2024-03-05) + + +### Bug Fixes + +* Docker version releases by removing arm/v6 and arm/v7 support ([#8976](https://github.com/parse-community/parse-server/issues/8976)) ([1f62dd0](https://github.com/parse-community/parse-server/commit/1f62dd0f4e107b22a387692558a042ee26ce8703)) + +# [7.0.0-alpha.23](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.22...7.0.0-alpha.23) (2024-03-03) + + +### Features + +* Add support for MongoDB query comment ([#8928](https://github.com/parse-community/parse-server/issues/8928)) ([2170962](https://github.com/parse-community/parse-server/commit/2170962a50fa353ed85eda3f11dce7ee3647b087)) + +# [7.0.0-alpha.22](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.21...7.0.0-alpha.22) (2024-03-02) + + +### Features + +* Switch GraphQL server from Yoga v2 to Apollo v4 ([#8959](https://github.com/parse-community/parse-server/issues/8959)) ([105ae7c](https://github.com/parse-community/parse-server/commit/105ae7c8a57d5a650b243174a80c26bf6db16e28)) + +# [7.0.0-alpha.21](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.20...7.0.0-alpha.21) (2024-03-01) + + +### Bug Fixes + +* Deny request if master key is not set in Parse Server option `masterKeyIps` regardless of ACL and CLP ([#8957](https://github.com/parse-community/parse-server/issues/8957)) ([a7b5b38](https://github.com/parse-community/parse-server/commit/a7b5b38418cbed9be3f4a7665f25b97f592663e1)) + + +### BREAKING CHANGES + +* A request using the master key will now be rejected as unauthorized if the IP from which the request originates is not set in the Parse Server option `masterKeyIps`, even if the request does not require the master key permission, for example for a public object in a public class class. ([a7b5b38](a7b5b38)) + +# [7.0.0-alpha.20](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.19...7.0.0-alpha.20) (2024-03-01) + + +### Bug Fixes + +* Improve PostgreSQL injection detection; fixes security vulnerability [GHSA-6927-3vr9-fxf2](https://github.com/parse-community/parse-server/security/advisories/GHSA-6927-3vr9-fxf2) which affects Parse Server deployments using a Postgres database ([#8961](https://github.com/parse-community/parse-server/issues/8961)) ([cbefe77](https://github.com/parse-community/parse-server/commit/cbefe770a7260b54748a058b8a7389937dc35833)) + +# [7.0.0-alpha.19](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.18...7.0.0-alpha.19) (2024-02-15) + + +### Features + +* Node process exits with error code 1 on uncaught exception to allow custom uncaught exception handling ([#8894](https://github.com/parse-community/parse-server/issues/8894)) ([70c280c](https://github.com/parse-community/parse-server/commit/70c280ca578ff28b5acf92f37fbe06d42a5b34ca)) + + +### BREAKING CHANGES + +* Node process now exits with code 1 on uncaught exceptions, enabling custom handlers that were blocked by Parse Server's default behavior of re-throwing errors. This change may lead to automatic process restarts by the environment, unlike before. ([70c280c](70c280c)) + +# [7.0.0-alpha.18](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.17...7.0.0-alpha.18) (2024-02-15) + + +### Features + +* Deprecation DEPPS6: Authentication adapters disabled by default ([#8858](https://github.com/parse-community/parse-server/issues/8858)) ([0cf58eb](https://github.com/parse-community/parse-server/commit/0cf58eb8d60c8e5f485764e154f3214c49eee430)) + + +### BREAKING CHANGES + +* Authentication adapters are disabled by default; to use an authentication adapter it needs to be explicitly enabled in the Parse Server authentication adapter option `auth..enabled: true` ([0cf58eb](0cf58eb)) + +# [7.0.0-alpha.17](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.16...7.0.0-alpha.17) (2024-02-15) + + +### Features + +* Deprecation DEPPS8: Parse Server option `allowExpiredAuthDataToken` defaults to `false` ([#8860](https://github.com/parse-community/parse-server/issues/8860)) ([e29845f](https://github.com/parse-community/parse-server/commit/e29845f8dacac09ce3093d75c0d92330c24389e8)) + + +### BREAKING CHANGES + +* Parse Server option `allowExpiredAuthDataToken` defaults to `false`; a 3rd party authentication token will be validated every time the user tries to log in and the login will fail if the token has expired; the effect of this change may differ for different authentication adapters, depending on the token lifetime and the token refresh logic of the adapter ([e29845f](e29845f)) + +# [7.0.0-alpha.16](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.15...7.0.0-alpha.16) (2024-02-14) + + +### Features + +* Deprecation DEPPS9: LiveQuery `fields` option is renamed to `keys` ([#8852](https://github.com/parse-community/parse-server/issues/8852)) ([38983e8](https://github.com/parse-community/parse-server/commit/38983e8e9b5cdbd006f311a2338103624137d013)) + + +### BREAKING CHANGES + +* LiveQuery `fields` option is renamed to `keys` ([38983e8](38983e8)) + +# [7.0.0-alpha.15](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.14...7.0.0-alpha.15) (2024-02-14) + + +### Features + +* Deprecation DEPPS7: Remove deprecated Cloud Code file trigger syntax ([#8855](https://github.com/parse-community/parse-server/issues/8855)) ([4e6a375](https://github.com/parse-community/parse-server/commit/4e6a375b5184ae0f7aa256a921eca4021c609435)) + + +### BREAKING CHANGES + +* Cloud Code file trigger syntax has been aligned with object trigger syntax, for example `Parse.Cloud.beforeDeleteFile'` has been changed to `Parse.Cloud.beforeDelete(Parse.File, (request) => {})'` ([4e6a375](4e6a375)) + +# [7.0.0-alpha.14](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.13...7.0.0-alpha.14) (2024-02-14) + + +### Bug Fixes + +* GraphQL file upload fails in case of use of pointer or relation ([#8721](https://github.com/parse-community/parse-server/issues/8721)) ([1aba638](https://github.com/parse-community/parse-server/commit/1aba6382c873fb489d4a898d301e6da9fb6aa61b)) + +# [7.0.0-alpha.13](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.12...7.0.0-alpha.13) (2024-02-14) + + +### Bug Fixes + +* Docker image not published to Docker Hub on new release ([#8905](https://github.com/parse-community/parse-server/issues/8905)) ([a2ac8d1](https://github.com/parse-community/parse-server/commit/a2ac8d133c71cd7b61e5ef59c4be915cfea85db6)) + +# [7.0.0-alpha.12](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.11...7.0.0-alpha.12) (2024-02-14) + + +### Features + +* Add support for Node 20, drop support for Node 14, 16 ([#8907](https://github.com/parse-community/parse-server/issues/8907)) ([ced4872](https://github.com/parse-community/parse-server/commit/ced487246ea0ef72a8aa014991f003209b34841e)) + + +### BREAKING CHANGES + +* Removes support for Node 14 and 16 ([ced4872](ced4872)) + +# [7.0.0-alpha.11](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.10...7.0.0-alpha.11) (2024-01-22) + + +### Features + +* Add support for Postgres 16 ([#8898](https://github.com/parse-community/parse-server/issues/8898)) ([99489b2](https://github.com/parse-community/parse-server/commit/99489b22e4f0982e6cb39992974b51aa8d3a31e4)) + + +### BREAKING CHANGES + +* Removes support for Postgres 11 and 12 ([99489b2](99489b2)) + +# [7.0.0-alpha.10](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.9...7.0.0-alpha.10) (2024-01-17) + + +### Features + +* Add password validation via POST request for user with unverified email using master key and option `ignoreEmailVerification` ([#8895](https://github.com/parse-community/parse-server/issues/8895)) ([633a9d2](https://github.com/parse-community/parse-server/commit/633a9d25e4253e2125bc93c02ee8a37e0f5f7b83)) + +# [7.0.0-alpha.9](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.8...7.0.0-alpha.9) (2024-01-15) + + +### Bug Fixes + +* Server crashes when receiving an array of `Parse.Pointer` in the request body ([#8784](https://github.com/parse-community/parse-server/issues/8784)) ([66e3603](https://github.com/parse-community/parse-server/commit/66e36039d8af654cfa0284666c0ddd94975dcb52)) + +# [7.0.0-alpha.8](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.7...7.0.0-alpha.8) (2024-01-15) + + +### Bug Fixes + +* Incomplete user object in `verifyEmail` function if both username and email are changed ([#8889](https://github.com/parse-community/parse-server/issues/8889)) ([1eb95ae](https://github.com/parse-community/parse-server/commit/1eb95aeb41a96250e582d79a703f6adcb403c08b)) + +# [7.0.0-alpha.7](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.6...7.0.0-alpha.7) (2024-01-14) + + +### Bug Fixes + +* Username is `undefined` in email verification link on email change ([#8887](https://github.com/parse-community/parse-server/issues/8887)) ([e315c13](https://github.com/parse-community/parse-server/commit/e315c137bf41bedfa8f0df537f2c3f6ab45b7e60)) + +# [7.0.0-alpha.6](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.5...7.0.0-alpha.6) (2024-01-14) + + +### Bug Fixes + +* Parse Server option `emailVerifyTokenReuseIfValid: true` generates new token on every email verification request ([#8885](https://github.com/parse-community/parse-server/issues/8885)) ([0023ce4](https://github.com/parse-community/parse-server/commit/0023ce448a5e9423337d0e1a25648bde1156bc95)) + +# [7.0.0-alpha.5](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.4...7.0.0-alpha.5) (2024-01-06) + + +### Features + +* Add `installationId`, `ip`, `resendRequest` to arguments passed to `verifyUserEmails` on verification email request ([#8873](https://github.com/parse-community/parse-server/issues/8873)) ([8adcbee](https://github.com/parse-community/parse-server/commit/8adcbee11283d3e95179ca2047e2615f52c18806)) + + +### BREAKING CHANGES + +* The `Parse.User` passed as argument if `verifyUserEmails` is set to a function is renamed from `user` to `object` for consistency with invocations of `verifyUserEmails` on signup or login; the user object is not a plain JavaScript object anymore but an instance of `Parse.User` ([8adcbee](8adcbee)) + +# [7.0.0-alpha.4](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.3...7.0.0-alpha.4) (2023-12-27) + + +### Features + +* Add `Parse.User` as function parameter to Parse Server options `verifyUserEmails`, `preventLoginWithUnverifiedEmail` on login ([#8850](https://github.com/parse-community/parse-server/issues/8850)) ([972f630](https://github.com/parse-community/parse-server/commit/972f6300163b3cd7d95eeb95986e8322c95f821c)) + +# [7.0.0-alpha.3](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.2...7.0.0-alpha.3) (2023-12-26) + + +### Bug Fixes + +* Conditional email verification not working in some cases if `verifyUserEmails`, `preventLoginWithUnverifiedEmail` set to functions ([#8838](https://github.com/parse-community/parse-server/issues/8838)) ([8e7a6b1](https://github.com/parse-community/parse-server/commit/8e7a6b1480c0117e6c73e7adc5a6619115a04e85)) + +### Features + +* Allow `Parse.Session.current` on expired session token instead of throwing error ([#8722](https://github.com/parse-community/parse-server/issues/8722)) ([f9dde4a](https://github.com/parse-community/parse-server/commit/f9dde4a9f8a90c63f71172c9bc515b0f6c6d2e4a)) + + +### BREAKING CHANGES + +* `Parse.Session.current()` no longer throws an error if the session token is expired, but instead returns the session token with its expiration date to allow checking its validity ([f9dde4a](f9dde4a)) + +# [7.0.0-alpha.2](https://github.com/parse-community/parse-server/compare/7.0.0-alpha.1...7.0.0-alpha.2) (2023-12-17) + + +### Features + +* Add `installationId` to arguments for `verifyUserEmails`, `preventLoginWithUnverifiedEmail` ([#8836](https://github.com/parse-community/parse-server/issues/8836)) ([a22dbe1](https://github.com/parse-community/parse-server/commit/a22dbe16d5ac0090608f6caaf0ebd134925b7fd4)) + +# [7.0.0-alpha.1](https://github.com/parse-community/parse-server/compare/6.5.0-alpha.2...7.0.0-alpha.1) (2023-12-10) + + +### Features + +* Add support for MongoDB 7 ([#8761](https://github.com/parse-community/parse-server/issues/8761)) ([3de8494](https://github.com/parse-community/parse-server/commit/3de8494a221991dfd10a74e0a2dc89576265c9b7)) + + +### BREAKING CHANGES + +* `Parse.Query` no longer supports the BSON type `code`; although this feature was never officially documented, its removal is announced as a breaking change to protect deployments where it might be in use. ([3de8494](3de8494)) + +# [6.5.0-alpha.2](https://github.com/parse-community/parse-server/compare/6.5.0-alpha.1...6.5.0-alpha.2) (2023-11-19) + + +### Performance Improvements + +* Improved IP validation performance for `masterKeyIPs`, `maintenanceKeyIPs` ([#8510](https://github.com/parse-community/parse-server/issues/8510)) ([b87daba](https://github.com/parse-community/parse-server/commit/b87daba0671a1b0b7b8d63bc671d665c91a04522)) + +# [6.5.0-alpha.1](https://github.com/parse-community/parse-server/compare/6.4.0...6.5.0-alpha.1) (2023-11-18) + + +### Bug Fixes + +* Context not passed to Cloud Code Trigger `beforeFind` when using `Parse.Query.include` ([#8765](https://github.com/parse-community/parse-server/issues/8765)) ([7d32d89](https://github.com/parse-community/parse-server/commit/7d32d8934f3ae7af7a7d8b9cc6a829c7d73973d3)) +* Parse Server option `fileUpload.fileExtensions` fails to determine file extension if filename contains multiple dots ([#8754](https://github.com/parse-community/parse-server/issues/8754)) ([3d6d50e](https://github.com/parse-community/parse-server/commit/3d6d50e0afff18b95fb906914e2cebd3839b517a)) +* Security bump @babel/traverse from 7.20.5 to 7.23.2 ([#8777](https://github.com/parse-community/parse-server/issues/8777)) ([2d6b3d1](https://github.com/parse-community/parse-server/commit/2d6b3d18499179e99be116f25c0850d3f449509c)) +* Security upgrade graphql from 16.6.0 to 16.8.1 ([#8758](https://github.com/parse-community/parse-server/issues/8758)) ([71dfd8a](https://github.com/parse-community/parse-server/commit/71dfd8a7ece8c0dd1a66d03bb9420cfd39f4f9b1)) + +### Features + +* Add `$setOnInsert` operator to `Parse.Server.database.update` ([#8791](https://github.com/parse-community/parse-server/issues/8791)) ([f630a45](https://github.com/parse-community/parse-server/commit/f630a45aa5e87bc73a81fded061400c199b71a29)) +* Add compatibility for MongoDB Atlas Serverless and AWS Amazon DocumentDB with collation options `enableCollationCaseComparison`, `transformEmailToLowercase`, `transformUsernameToLowercase` ([#8805](https://github.com/parse-community/parse-server/issues/8805)) ([09fbeeb](https://github.com/parse-community/parse-server/commit/09fbeebba8870e7cf371fb84371a254c7b368620)) +* Add context to Cloud Code Triggers `beforeLogin` and `afterLogin` ([#8724](https://github.com/parse-community/parse-server/issues/8724)) ([a9c34ef](https://github.com/parse-community/parse-server/commit/a9c34ef1e2c78a42fb8b5fa8d569b7677c74919d)) +* Allow setting `createdAt` and `updatedAt` during `Parse.Object` creation with maintenance key ([#8696](https://github.com/parse-community/parse-server/issues/8696)) ([77bbfb3](https://github.com/parse-community/parse-server/commit/77bbfb3f186f5651c33ba152f04cff95128eaf2d)) +* Upgrade Parse Server Push Adapter to 5.0.2 ([#8813](https://github.com/parse-community/parse-server/issues/8813)) ([6ef1986](https://github.com/parse-community/parse-server/commit/6ef1986c03a1d84b7e11c05851e5bf9688d88740)) + +# [6.4.0-alpha.8](https://github.com/parse-community/parse-server/compare/6.4.0-alpha.7...6.4.0-alpha.8) (2023-11-13) + + +### Features + +* Add compatibility for MongoDB Atlas Serverless and AWS Amazon DocumentDB with collation options `enableCollationCaseComparison`, `transformEmailToLowercase`, `transformUsernameToLowercase` ([#8805](https://github.com/parse-community/parse-server/issues/8805)) ([09fbeeb](https://github.com/parse-community/parse-server/commit/09fbeebba8870e7cf371fb84371a254c7b368620)) + +# [6.4.0-alpha.7](https://github.com/parse-community/parse-server/compare/6.4.0-alpha.6...6.4.0-alpha.7) (2023-10-25) + + +### Features + +* Add `$setOnInsert` operator to `Parse.Server.database.update` ([#8791](https://github.com/parse-community/parse-server/issues/8791)) ([f630a45](https://github.com/parse-community/parse-server/commit/f630a45aa5e87bc73a81fded061400c199b71a29)) + +# [6.4.0-alpha.6](https://github.com/parse-community/parse-server/compare/6.4.0-alpha.5...6.4.0-alpha.6) (2023-10-18) + + +### Bug Fixes + +* Security bump @babel/traverse from 7.20.5 to 7.23.2 ([#8777](https://github.com/parse-community/parse-server/issues/8777)) ([2d6b3d1](https://github.com/parse-community/parse-server/commit/2d6b3d18499179e99be116f25c0850d3f449509c)) + +# [6.4.0-alpha.5](https://github.com/parse-community/parse-server/compare/6.4.0-alpha.4...6.4.0-alpha.5) (2023-10-14) + + +### Bug Fixes + +* Context not passed to Cloud Code Trigger `beforeFind` when using `Parse.Query.include` ([#8765](https://github.com/parse-community/parse-server/issues/8765)) ([7d32d89](https://github.com/parse-community/parse-server/commit/7d32d8934f3ae7af7a7d8b9cc6a829c7d73973d3)) + +# [6.4.0-alpha.4](https://github.com/parse-community/parse-server/compare/6.4.0-alpha.3...6.4.0-alpha.4) (2023-09-29) + + +### Features + +* Allow setting `createdAt` and `updatedAt` during `Parse.Object` creation with maintenance key ([#8696](https://github.com/parse-community/parse-server/issues/8696)) ([77bbfb3](https://github.com/parse-community/parse-server/commit/77bbfb3f186f5651c33ba152f04cff95128eaf2d)) + +# [6.4.0-alpha.3](https://github.com/parse-community/parse-server/compare/6.4.0-alpha.2...6.4.0-alpha.3) (2023-09-23) + + +### Bug Fixes + +* Parse Server option `fileUpload.fileExtensions` fails to determine file extension if filename contains multiple dots ([#8754](https://github.com/parse-community/parse-server/issues/8754)) ([3d6d50e](https://github.com/parse-community/parse-server/commit/3d6d50e0afff18b95fb906914e2cebd3839b517a)) + +# [6.4.0-alpha.2](https://github.com/parse-community/parse-server/compare/6.4.0-alpha.1...6.4.0-alpha.2) (2023-09-22) + + +### Bug Fixes + +* Security upgrade graphql from 16.6.0 to 16.8.1 ([#8758](https://github.com/parse-community/parse-server/issues/8758)) ([71dfd8a](https://github.com/parse-community/parse-server/commit/71dfd8a7ece8c0dd1a66d03bb9420cfd39f4f9b1)) + +# [6.4.0-alpha.1](https://github.com/parse-community/parse-server/compare/6.3.0...6.4.0-alpha.1) (2023-09-20) + +### Features + +* Add context to Cloud Code Triggers `beforeLogin` and `afterLogin` ([#8724](https://github.com/parse-community/parse-server/issues/8724)) ([a9c34ef](https://github.com/parse-community/parse-server/commit/a9c34ef1e2c78a42fb8b5fa8d569b7677c74919d)) + +# [6.3.0-alpha.9](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.8...6.3.0-alpha.9) (2023-09-13) + + +### Performance Improvements + +* Improve performance of recursive pointer iterations ([#8741](https://github.com/parse-community/parse-server/issues/8741)) ([45a3ed0](https://github.com/parse-community/parse-server/commit/45a3ed0fcf2c0170607505a1550fb15896e705fd)) + +# [6.3.0-alpha.8](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.7...6.3.0-alpha.8) (2023-08-30) + + +### Bug Fixes + +* Redis 4 does not reconnect after unhandled error ([#8706](https://github.com/parse-community/parse-server/issues/8706)) ([2b3d4e5](https://github.com/parse-community/parse-server/commit/2b3d4e5d3c85cd142f85af68dec51a8523548d49)) + +# [6.3.0-alpha.7](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.6...6.3.0-alpha.7) (2023-08-18) + + +### Bug Fixes + +* Remove config logging when launching Parse Server via CLI ([#8710](https://github.com/parse-community/parse-server/issues/8710)) ([ae68f0c](https://github.com/parse-community/parse-server/commit/ae68f0c31b741eeb83379c905c7ddfaa124436ec)) + +# [6.3.0-alpha.6](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.5...6.3.0-alpha.6) (2023-07-17) + + +### Bug Fixes + +* Parse Server option `fileUpload.fileExtensions` does not work with an array of extensions ([#8688](https://github.com/parse-community/parse-server/issues/8688)) ([6a4a00c](https://github.com/parse-community/parse-server/commit/6a4a00ca7af1163ea74b047b85cd6817366b824b)) + +# [6.3.0-alpha.5](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.4...6.3.0-alpha.5) (2023-07-05) + + +### Features + +* Add property `Parse.Server.version` to determine current version of Parse Server in Cloud Code ([#8670](https://github.com/parse-community/parse-server/issues/8670)) ([a9d376b](https://github.com/parse-community/parse-server/commit/a9d376b61f5b07806eafbda91c4e36c322f09298)) + +# [6.3.0-alpha.4](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.3...6.3.0-alpha.4) (2023-07-04) + + +### Bug Fixes + +* Server does not start via CLI when `auth` option is set ([#8666](https://github.com/parse-community/parse-server/issues/8666)) ([4e2000b](https://github.com/parse-community/parse-server/commit/4e2000bc563324389584ace3c090a5c1a7796a64)) + +# [6.3.0-alpha.3](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.2...6.3.0-alpha.3) (2023-06-23) + + +### Features + +* Add TOTP authentication adapter ([#8457](https://github.com/parse-community/parse-server/issues/8457)) ([cc079a4](https://github.com/parse-community/parse-server/commit/cc079a40f6849a0e9bc6fdc811e8649ecb67b589)) + +# [6.3.0-alpha.2](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.1...6.3.0-alpha.2) (2023-06-20) + + +### Features + +* Add conditional email verification via dynamic Parse Server options `verifyUserEmails`, `sendUserEmailVerification` that now accept functions ([#8425](https://github.com/parse-community/parse-server/issues/8425)) ([44acd6d](https://github.com/parse-community/parse-server/commit/44acd6d9ed157ad4842200c9d01f9c77a05fec3a)) + +# [6.3.0-alpha.1](https://github.com/parse-community/parse-server/compare/6.2.0...6.3.0-alpha.1) (2023-06-18) + + +### Bug Fixes + +* Cloud Code Trigger `afterSave` executes even if not set ([#8520](https://github.com/parse-community/parse-server/issues/8520)) ([afd0515](https://github.com/parse-community/parse-server/commit/afd0515e207bd947840579d3f245980dffa6f804)) +* GridFS file storage doesn't work with certain `enableSchemaHooks` settings ([#8467](https://github.com/parse-community/parse-server/issues/8467)) ([d4cda4b](https://github.com/parse-community/parse-server/commit/d4cda4b26c9bde8c812549b8780bea1cfabdb394)) +* Inaccurate table total row count for PostgreSQL ([#8511](https://github.com/parse-community/parse-server/issues/8511)) ([0823a02](https://github.com/parse-community/parse-server/commit/0823a02fbf80bc88dc403bc47e9f5c6597ea78b4)) +* LiveQuery server is not shut down properly when `handleShutdown` is called ([#8491](https://github.com/parse-community/parse-server/issues/8491)) ([967700b](https://github.com/parse-community/parse-server/commit/967700bdbc94c74f75ba84d2b3f4b9f3fd2dca0b)) +* Rate limit feature is incompatible with Node 14 ([#8578](https://github.com/parse-community/parse-server/issues/8578)) ([f911f2c](https://github.com/parse-community/parse-server/commit/f911f2cd3a8c45cd326272dcd681532764a3761e)) +* Unnecessary log entries by `extendSessionOnUse` ([#8562](https://github.com/parse-community/parse-server/issues/8562)) ([fd6a007](https://github.com/parse-community/parse-server/commit/fd6a0077f2e5cf83d65e52172ae5a950ab0f1eae)) + +### Features + +* `extendSessionOnUse` to automatically renew Parse Sessions ([#8505](https://github.com/parse-community/parse-server/issues/8505)) ([6f885d3](https://github.com/parse-community/parse-server/commit/6f885d36b94902fdfea873fc554dee83589e6029)) +* Add new Parse Server option `preventSignupWithUnverifiedEmail` to prevent returning a user without session token on sign-up with unverified email address ([#8451](https://github.com/parse-community/parse-server/issues/8451)) ([82da308](https://github.com/parse-community/parse-server/commit/82da30842a55980aa90cb7680fbf6db37ee16dab)) +* Add option to change the log level of logs emitted by Cloud Functions ([#8530](https://github.com/parse-community/parse-server/issues/8530)) ([2caea31](https://github.com/parse-community/parse-server/commit/2caea310be412d82b04a85716bc769ccc410316d)) +* Add support for `$eq` query constraint in LiveQuery ([#8614](https://github.com/parse-community/parse-server/issues/8614)) ([656d673](https://github.com/parse-community/parse-server/commit/656d673cf5dea354e4f2b3d4dc2b29a41d311b3e)) +* Add zones for rate limiting by `ip`, `user`, `session`, `global` ([#8508](https://github.com/parse-community/parse-server/issues/8508)) ([03fba97](https://github.com/parse-community/parse-server/commit/03fba97e0549bfcaeee9f2fa4c9905dbcc91840e)) +* Allow `Parse.Object` pointers in Cloud Code arguments ([#8490](https://github.com/parse-community/parse-server/issues/8490)) ([28aeda3](https://github.com/parse-community/parse-server/commit/28aeda3f160efcbbcf85a85484a8d26567fa9761)) + +### Reverts + +* fix: Inaccurate table total row count for PostgreSQL ([6722110](https://github.com/parse-community/parse-server/commit/6722110f203bc5fdcaa68cdf091cf9e7b48d1cff)) + +# [6.1.0-alpha.20](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.19...6.1.0-alpha.20) (2023-06-09) + + +### Features + +* Add zones for rate limiting by `ip`, `user`, `session`, `global` ([#8508](https://github.com/parse-community/parse-server/issues/8508)) ([03fba97](https://github.com/parse-community/parse-server/commit/03fba97e0549bfcaeee9f2fa4c9905dbcc91840e)) + +# [6.1.0-alpha.19](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.18...6.1.0-alpha.19) (2023-06-08) + + +### Bug Fixes + +* LiveQuery server is not shut down properly when `handleShutdown` is called ([#8491](https://github.com/parse-community/parse-server/issues/8491)) ([967700b](https://github.com/parse-community/parse-server/commit/967700bdbc94c74f75ba84d2b3f4b9f3fd2dca0b)) + +# [6.1.0-alpha.18](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.17...6.1.0-alpha.18) (2023-06-08) + + +### Features + +* Add support for `$eq` query constraint in LiveQuery ([#8614](https://github.com/parse-community/parse-server/issues/8614)) ([656d673](https://github.com/parse-community/parse-server/commit/656d673cf5dea354e4f2b3d4dc2b29a41d311b3e)) + +# [6.1.0-alpha.17](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.16...6.1.0-alpha.17) (2023-06-07) + + +### Features + +* Add new Parse Server option `preventSignupWithUnverifiedEmail` to prevent returning a user without session token on sign-up with unverified email address ([#8451](https://github.com/parse-community/parse-server/issues/8451)) ([82da308](https://github.com/parse-community/parse-server/commit/82da30842a55980aa90cb7680fbf6db37ee16dab)) + +# [6.1.0-alpha.16](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.15...6.1.0-alpha.16) (2023-05-28) + + +### Reverts + +* fix: Inaccurate table total row count for PostgreSQL ([6722110](https://github.com/parse-community/parse-server/commit/6722110f203bc5fdcaa68cdf091cf9e7b48d1cff)) + +# [6.1.0-alpha.15](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.14...6.1.0-alpha.15) (2023-05-28) + + +### Bug Fixes + +* Inaccurate table total row count for PostgreSQL ([#8511](https://github.com/parse-community/parse-server/issues/8511)) ([0823a02](https://github.com/parse-community/parse-server/commit/0823a02fbf80bc88dc403bc47e9f5c6597ea78b4)) + +# [6.1.0-alpha.14](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.13...6.1.0-alpha.14) (2023-05-27) + + +### Bug Fixes + +* Unnecessary log entries by `extendSessionOnUse` ([#8562](https://github.com/parse-community/parse-server/issues/8562)) ([fd6a007](https://github.com/parse-community/parse-server/commit/fd6a0077f2e5cf83d65e52172ae5a950ab0f1eae)) + +### Features + +* Allow `Parse.Object` pointers in Cloud Code arguments ([#8490](https://github.com/parse-community/parse-server/issues/8490)) ([28aeda3](https://github.com/parse-community/parse-server/commit/28aeda3f160efcbbcf85a85484a8d26567fa9761)) + +# [6.1.0-alpha.13](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.12...6.1.0-alpha.13) (2023-05-25) + + +### Bug Fixes + +* Rate limit feature is incompatible with Node 14 ([#8578](https://github.com/parse-community/parse-server/issues/8578)) ([f911f2c](https://github.com/parse-community/parse-server/commit/f911f2cd3a8c45cd326272dcd681532764a3761e)) + +# [6.1.0-alpha.12](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.11...6.1.0-alpha.12) (2023-05-19) + + +### Bug Fixes + +* GridFS file storage doesn't work with certain `enableSchemaHooks` settings ([#8467](https://github.com/parse-community/parse-server/issues/8467)) ([d4cda4b](https://github.com/parse-community/parse-server/commit/d4cda4b26c9bde8c812549b8780bea1cfabdb394)) + +# [6.1.0-alpha.11](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.10...6.1.0-alpha.11) (2023-05-17) + + +### Features + +* `extendSessionOnUse` to automatically renew Parse Sessions ([#8505](https://github.com/parse-community/parse-server/issues/8505)) ([6f885d3](https://github.com/parse-community/parse-server/commit/6f885d36b94902fdfea873fc554dee83589e6029)) + +# [6.1.0-alpha.10](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.9...6.1.0-alpha.10) (2023-05-12) + + +### Bug Fixes + +* Cloud Code Trigger `afterSave` executes even if not set ([#8520](https://github.com/parse-community/parse-server/issues/8520)) ([afd0515](https://github.com/parse-community/parse-server/commit/afd0515e207bd947840579d3f245980dffa6f804)) + +# [6.1.0-alpha.9](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.8...6.1.0-alpha.9) (2023-05-09) + + +### Features + +* Add option to change the log level of logs emitted by Cloud Functions ([#8530](https://github.com/parse-community/parse-server/issues/8530)) ([2caea31](https://github.com/parse-community/parse-server/commit/2caea310be412d82b04a85716bc769ccc410316d)) + +# [6.1.0-alpha.8](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.7...6.1.0-alpha.8) (2023-05-01) + + +### Features + +* Allow multiple origins for header `Access-Control-Allow-Origin` ([#8517](https://github.com/parse-community/parse-server/issues/8517)) ([4f15539](https://github.com/parse-community/parse-server/commit/4f15539ac244aa2d393ac5177f7604b43f69e271)) + +# [6.1.0-alpha.7](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.6...6.1.0-alpha.7) (2023-03-10) + + +### Bug Fixes + +* Rate limiting across multiple servers via Redis not working ([#8469](https://github.com/parse-community/parse-server/issues/8469)) ([d9e347d](https://github.com/parse-community/parse-server/commit/d9e347d7413f30f58ffbb8397fc8b5ae23be6ff0)) + +# [6.1.0-alpha.6](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.5...6.1.0-alpha.6) (2023-03-06) + + +### Features + +* Add rate limiting across multiple servers via Redis ([#8394](https://github.com/parse-community/parse-server/issues/8394)) ([34833e4](https://github.com/parse-community/parse-server/commit/34833e42eec08b812b733be78df0535ab0e096b6)) + +# [6.1.0-alpha.5](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.4...6.1.0-alpha.5) (2023-03-06) + + +### Bug Fixes + +* LiveQuery can return incorrectly formatted date ([#8456](https://github.com/parse-community/parse-server/issues/8456)) ([4ce135a](https://github.com/parse-community/parse-server/commit/4ce135a4fe930776044bc8fd786a4e17a0144e03)) + +# [6.1.0-alpha.4](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.3...6.1.0-alpha.4) (2023-03-06) + + +### Bug Fixes + +* Parameters missing in `afterFind` trigger of authentication adapters ([#8458](https://github.com/parse-community/parse-server/issues/8458)) ([ce34747](https://github.com/parse-community/parse-server/commit/ce34747e8af54cb0b6b975da38f779a5955d2d59)) + +# [6.1.0-alpha.3](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.2...6.1.0-alpha.3) (2023-03-06) + + +### Features + +* Add `afterFind` trigger to authentication adapters ([#8444](https://github.com/parse-community/parse-server/issues/8444)) ([c793bb8](https://github.com/parse-community/parse-server/commit/c793bb88e7485743c7ceb65fe419cde75833ff33)) + +# [6.1.0-alpha.2](https://github.com/parse-community/parse-server/compare/6.1.0-alpha.1...6.1.0-alpha.2) (2023-03-05) + + +### Bug Fixes + +* Nested date is incorrectly decoded as empty object `{}` when fetching a Parse Object ([#8446](https://github.com/parse-community/parse-server/issues/8446)) ([22d2446](https://github.com/parse-community/parse-server/commit/22d2446dfea2bc339affc20535d181097e152acf)) + +# [6.1.0-alpha.1](https://github.com/parse-community/parse-server/compare/6.0.0...6.1.0-alpha.1) (2023-03-03) + + +### Bug Fixes + +* Security upgrade jsonwebtoken to 9.0.0 ([#8420](https://github.com/parse-community/parse-server/issues/8420)) ([f5bfe45](https://github.com/parse-community/parse-server/commit/f5bfe4571e82b2b7440d41f3cff0d49937398164)) + +### Features + +* Add option `schemaCacheTtl` for schema cache pulling as alternative to `enableSchemaHooks` ([#8436](https://github.com/parse-community/parse-server/issues/8436)) ([b3b76de](https://github.com/parse-community/parse-server/commit/b3b76de71b1d4265689d052e7837c38ec1fa4323)) +* Add Parse Server option `resetPasswordSuccessOnInvalidEmail` to choose success or error response on password reset with invalid email ([#7551](https://github.com/parse-community/parse-server/issues/7551)) ([e5d610e](https://github.com/parse-community/parse-server/commit/e5d610e5e487ddab86409409ac3d7362aba8f59b)) +* Deprecate LiveQuery `fields` option in favor of `keys` for semantic consistency ([#8388](https://github.com/parse-community/parse-server/issues/8388)) ([a49e323](https://github.com/parse-community/parse-server/commit/a49e323d5ae640bff1c6603ec37fdaddb9328dd1)) +* Export `AuthAdapter` to make it available for extension with custom authentication adapters ([#8443](https://github.com/parse-community/parse-server/issues/8443)) ([40c1961](https://github.com/parse-community/parse-server/commit/40c196153b8efa12ae384c1c0092b2ed60a260d6)) + +# [6.0.0-alpha.35](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.34...6.0.0-alpha.35) (2023-02-27) + + +### Features + +* Add option `schemaCacheTtl` for schema cache pulling as alternative to `enableSchemaHooks` ([#8436](https://github.com/parse-community/parse-server/issues/8436)) ([b3b76de](https://github.com/parse-community/parse-server/commit/b3b76de71b1d4265689d052e7837c38ec1fa4323)) + +# [6.0.0-alpha.34](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.33...6.0.0-alpha.34) (2023-02-24) + + +### Features + +* Add Parse Server option `resetPasswordSuccessOnInvalidEmail` to choose success or error response on password reset with invalid email ([#7551](https://github.com/parse-community/parse-server/issues/7551)) ([e5d610e](https://github.com/parse-community/parse-server/commit/e5d610e5e487ddab86409409ac3d7362aba8f59b)) + +# [6.0.0-alpha.33](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.32...6.0.0-alpha.33) (2023-02-17) + + +### Features + +* Deprecate LiveQuery `fields` option in favor of `keys` for semantic consistency ([#8388](https://github.com/parse-community/parse-server/issues/8388)) ([a49e323](https://github.com/parse-community/parse-server/commit/a49e323d5ae640bff1c6603ec37fdaddb9328dd1)) + +# [6.0.0-alpha.32](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.31...6.0.0-alpha.32) (2023-02-07) + + +### Bug Fixes + +* Security upgrade jsonwebtoken to 9.0.0 ([#8420](https://github.com/parse-community/parse-server/issues/8420)) ([f5bfe45](https://github.com/parse-community/parse-server/commit/f5bfe4571e82b2b7440d41f3cff0d49937398164)) + +# [6.0.0-alpha.31](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.30...6.0.0-alpha.31) (2023-01-31) + + +### Bug Fixes + +* Parse Server option `requestKeywordDenylist` can be bypassed via Cloud Code Webhooks or Triggers; fixes security vulnerability [GHSA-xprv-wvh7-qqqx](https://github.com/parse-community/parse-server/security/advisories/GHSA-xprv-wvh7-qqqx) ([#8302](https://github.com/parse-community/parse-server/issues/8302)) ([6728da1](https://github.com/parse-community/parse-server/commit/6728da1e3591db1e27031d335d64d8f25546a06f)) +* Prototype pollution via Cloud Code Webhooks; fixes security vulnerability [GHSA-93vw-8fm5-p2jf](https://github.com/parse-community/parse-server/security/advisories/GHSA-93vw-8fm5-p2jf) ([#8305](https://github.com/parse-community/parse-server/issues/8305)) ([60c5a73](https://github.com/parse-community/parse-server/commit/60c5a73d257e0d536056b38bdafef8b7130524d8)) +* Remote code execution via MongoDB BSON parser through prototype pollution; fixes security vulnerability [GHSA-prm5-8g2m-24gg](https://github.com/parse-community/parse-server/security/advisories/GHSA-prm5-8g2m-24gg) ([#8295](https://github.com/parse-community/parse-server/issues/8295)) ([50eed3c](https://github.com/parse-community/parse-server/commit/50eed3cffe80fadfb4bdac52b2783a18da2cfc4f)) + +# [6.0.0-alpha.30](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.29...6.0.0-alpha.30) (2023-01-27) + + +### Bug Fixes + +* Schema without class level permissions may cause error ([#8409](https://github.com/parse-community/parse-server/issues/8409)) ([aa2cd51](https://github.com/parse-community/parse-server/commit/aa2cd51b703388d925e4572e5c2b2d883c68e49c)) + +# [6.0.0-alpha.29](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.28...6.0.0-alpha.29) (2023-01-26) + + +### Features + +* Upgrade to Parse JavaScript SDK 4 ([#8332](https://github.com/parse-community/parse-server/issues/8332)) ([9092874](https://github.com/parse-community/parse-server/commit/9092874a9a482a24dfdce1dce56615702999d6b8)) + +# [6.0.0-alpha.28](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.27...6.0.0-alpha.28) (2023-01-25) + + +### Bug Fixes + +* Rate limiter may reject requests that contain a session token ([#8399](https://github.com/parse-community/parse-server/issues/8399)) ([c114dc8](https://github.com/parse-community/parse-server/commit/c114dc8831055d74187b9dfb4c9eeb558520237c)) + +# [6.0.0-alpha.27](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.26...6.0.0-alpha.27) (2023-01-23) + + +### Bug Fixes + +* `ParseServer.verifyServerUrl` may fail if server response headers are missing; remove unnecessary logging ([#8391](https://github.com/parse-community/parse-server/issues/8391)) ([1c37a7c](https://github.com/parse-community/parse-server/commit/1c37a7cd0715949a70b220a629071c7dab7d5e7b)) + +# [6.0.0-alpha.26](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.25...6.0.0-alpha.26) (2023-01-20) + + +### Bug Fixes + +* ES6 modules do not await the import of Cloud Code files ([#8368](https://github.com/parse-community/parse-server/issues/8368)) ([a7bd180](https://github.com/parse-community/parse-server/commit/a7bd180cddd784c8735622f22e012c342ad535fb)) + +# [6.0.0-alpha.25](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.24...6.0.0-alpha.25) (2023-01-16) + + +### Features + +* Add `ParseQuery.watch` to trigger LiveQuery only on update of specific fields ([#8028](https://github.com/parse-community/parse-server/issues/8028)) ([fc92faa](https://github.com/parse-community/parse-server/commit/fc92faac75107b3392eeddd916c4c5b45e3c5e0c)) + +# [6.0.0-alpha.24](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.23...6.0.0-alpha.24) (2023-01-09) + + +### Features + +* Reduce Docker image size by improving stages ([#8359](https://github.com/parse-community/parse-server/issues/8359)) ([40810b4](https://github.com/parse-community/parse-server/commit/40810b48ebde8b1f21d2448a3a4de0585b1b5e34)) + + +### BREAKING CHANGES + +* The Docker image does not contain the git dependency anymore; if you have been using git as a transitive dependency it now needs to be explicitly installed in your Docker file, for example with `RUN apk --no-cache add git` (#8359) ([40810b4](40810b4)) + +# [6.0.0-alpha.23](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.22...6.0.0-alpha.23) (2023-01-08) + + +### Features + +* Access the internal scope of Parse Server using the new `maintenanceKey`; the internal scope contains unofficial and undocumented fields (prefixed with underscore `_`) which are used internally by Parse Server; you may want to manipulate these fields for out-of-band changes such as data migration or correction tasks; changes within the internal scope of Parse Server may happen at any time without notice or changelog entry, it is therefore recommended to look at the source code of Parse Server to understand the effects of manipulating internal fields before using the key; it is discouraged to use the `maintenanceKey` for routine operations in a production environment; see [access scopes](https://github.com/parse-community/parse-server#access-scopes) ([#8212](https://github.com/parse-community/parse-server/issues/8212)) ([f3bcc93](https://github.com/parse-community/parse-server/commit/f3bcc9365cd6f08b0a32c132e8e5ff6d1b650863)) + + +### BREAKING CHANGES + +* Fields in the internal scope of Parse Server (prefixed with underscore `_`) are only returned using the new `maintenanceKey`; previously the `masterKey` allowed reading of internal fields; see [access scopes](https://github.com/parse-community/parse-server#access-scopes) for a comparison of the keys' access permissions (#8212) ([f3bcc93](f3bcc93)) + +# [6.0.0-alpha.22](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.21...6.0.0-alpha.22) (2023-01-08) + + +### Features + +* Adapt `verifyServerUrl` for new asynchronous Parse Server start-up states ([#8366](https://github.com/parse-community/parse-server/issues/8366)) ([ffa4974](https://github.com/parse-community/parse-server/commit/ffa4974158615fbff4a2692b9db41dcb50d3f77b)) + + +### BREAKING CHANGES + +* The method `ParseServer.verifyServerUrl` now returns a promise instead of a callback. ([ffa4974](ffa4974)) + +# [6.0.0-alpha.21](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.20...6.0.0-alpha.21) (2023-01-06) + + +### Features + +* Add request rate limiter based on IP address ([#8174](https://github.com/parse-community/parse-server/issues/8174)) ([6c79f6a](https://github.com/parse-community/parse-server/commit/6c79f6a69e25e47846e3b0685d6bdfd6b91086b1)) + +# [6.0.0-alpha.20](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.19...6.0.0-alpha.20) (2023-01-06) + + +### Features + +* Add Node 19 support ([#8363](https://github.com/parse-community/parse-server/issues/8363)) ([a4990dc](https://github.com/parse-community/parse-server/commit/a4990dcd29abcb4442f3c424aff482a0a116160f)) + +# [6.0.0-alpha.19](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.18...6.0.0-alpha.19) (2023-01-05) + + +### Features + +* Remove deprecation `DEPPS1`: Native MongoDB syntax in aggregation pipeline ([#8362](https://github.com/parse-community/parse-server/issues/8362)) ([d0d30c4](https://github.com/parse-community/parse-server/commit/d0d30c4f1394f563724644a8fc81734be538a2c0)) + + +### BREAKING CHANGES + +* The MongoDB aggregation pipeline requires native MongoDB syntax instead of the custom Parse Server syntax; for example pipeline stage names require a leading dollar sign like `$match` and the MongoDB document ID is referenced using `_id` instead of `objectId` (#8362) ([d0d30c4](d0d30c4)) + +# [6.0.0-alpha.18](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.17...6.0.0-alpha.18) (2023-01-05) + + +### Bug Fixes + +* The client IP address may be determined incorrectly in some cases; this fixes a security vulnerability in which the Parse Server option `masterKeyIps` may be circumvented, see [GHSA-vm5r-c87r-pf6x](https://github.com/parse-community/parse-server/security/advisories/GHSA-vm5r-c87r-pf6x) ([#8372](https://github.com/parse-community/parse-server/issues/8372)) ([892040d](https://github.com/parse-community/parse-server/commit/892040dc2f82a3e2abe2824e4b553521b6f894de)) + + +### BREAKING CHANGES + +* The mechanism to determine the client IP address has been rewritten; to correctly determine the IP address it is now required to set the Parse Server option `trustProxy` accordingly if Parse Server runs behind a proxy server, see the express framework's [trust proxy](https://expressjs.com/en/guide/behind-proxies.html) setting (#8372) ([892040d](892040d)) + +# [6.0.0-alpha.17](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.16...6.0.0-alpha.17) (2022-12-22) + + +### Features + +* Upgrade Node Package Manager lock file `package-lock.json` to version 2 ([#8285](https://github.com/parse-community/parse-server/issues/8285)) ([ee72467](https://github.com/parse-community/parse-server/commit/ee7246733d63e4bda20401f7b00262ff03299f20)) + + +### BREAKING CHANGES + +* The Node Package Manager lock file `package-lock.json` is upgraded to version 2; while it is backwards with version 1 for the npm installer, consider this if you run any non-npm analysis tools that use the lock file (#8285) ([ee72467](ee72467)) + +# [6.0.0-alpha.16](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.15...6.0.0-alpha.16) (2022-12-21) + + +### Features + +* Asynchronous initialization of Parse Server ([#8232](https://github.com/parse-community/parse-server/issues/8232)) ([99fcf45](https://github.com/parse-community/parse-server/commit/99fcf45e55c368de2345b0c4d780e70e0adf0e15)) + + +### BREAKING CHANGES + +* This release introduces the asynchronous initialization of Parse Server to prevent mounting Parse Server before being ready to receive request; it changes how Parse Server is imported, initialized and started; it also removes the callback `serverStartComplete`; see the [Parse Server 6 migration guide](https://github.com/parse-community/parse-server/blob/alpha/6.0.0.md) for more details (#8232) ([99fcf45](99fcf45)) + +# [6.0.0-alpha.15](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.14...6.0.0-alpha.15) (2022-12-20) + + +### Bug Fixes + +* Nested objects are encoded incorrectly for MongoDB ([#8209](https://github.com/parse-community/parse-server/issues/8209)) ([1412666](https://github.com/parse-community/parse-server/commit/1412666f75829612de6fb9d7ccae35761c9b75cb)) + + +### BREAKING CHANGES + +* Nested objects are now properly stored in the database using JSON serialization; previously, due to a bug only top-level objects were serialized, but nested objects were saved as raw JSON; for example, a nested `Date` object was saved as a JSON object like `{ "__type": "Date", "iso": "2020-01-01T00:00:00.000Z" }` instead of its serialized representation `2020-01-01T00:00:00.000Z` (#8209) ([1412666](1412666)) + +# [6.0.0-alpha.14](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.13...6.0.0-alpha.14) (2022-12-16) + + +### Features + +* Write log entry when request with master key is rejected as outside of `masterKeyIps` ([#8350](https://github.com/parse-community/parse-server/issues/8350)) ([e22b73d](https://github.com/parse-community/parse-server/commit/e22b73d4b700c8ff745aa81726c6680082294b45)) + +# [6.0.0-alpha.13](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.12...6.0.0-alpha.13) (2022-12-07) + + +### Features + +* Add option to change the log level of the logs emitted by triggers ([#8328](https://github.com/parse-community/parse-server/issues/8328)) ([8f3b694](https://github.com/parse-community/parse-server/commit/8f3b694e39d4a966567e50dbea4d62e954fa5c06)) + +# [6.0.0-alpha.12](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.11...6.0.0-alpha.12) (2022-11-26) + + +### Features + +* Upgrade Redis 3 to 4 for LiveQuery ([#8333](https://github.com/parse-community/parse-server/issues/8333)) ([b2761fb](https://github.com/parse-community/parse-server/commit/b2761fb3786b519d9bbcf35be54309d2d35da1a9)) + +# [6.0.0-alpha.11](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.10...6.0.0-alpha.11) (2022-11-25) + + +### Bug Fixes + +* Parse Server option `masterKeyIps` does not include localhost by default for IPv6 ([#8322](https://github.com/parse-community/parse-server/issues/8322)) ([ab82635](https://github.com/parse-community/parse-server/commit/ab82635b0d4cf323a07ddee51fee587b43dce95c)) + +# [6.0.0-alpha.10](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.9...6.0.0-alpha.10) (2022-11-19) + + +### Bug Fixes + +* Cloud Code trigger `beforeSave` does not work with `Parse.Role` ([#8320](https://github.com/parse-community/parse-server/issues/8320)) ([f29d972](https://github.com/parse-community/parse-server/commit/f29d9720e9b37918fd885c97a31e34c42750e724)) + +# [6.0.0-alpha.9](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.8...6.0.0-alpha.9) (2022-11-16) + + +### Features + +* Remove deprecation `DEPPS3`: Config option `enforcePrivateUsers` defaults to `true` ([#8283](https://github.com/parse-community/parse-server/issues/8283)) ([ed499e3](https://github.com/parse-community/parse-server/commit/ed499e32a21bab9a874a9e5367dc71248ce836c4)) + + +### BREAKING CHANGES + +* The Parse Server option `enforcePrivateUsers` is set to `true` by default; in previous releases this option defaults to `false`; this change improves the default security configuration of Parse Server (#8283) ([ed499e3](ed499e3)) + +# [6.0.0-alpha.8](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.7...6.0.0-alpha.8) (2022-11-11) + + +### Features + +* Restrict use of `masterKey` to localhost by default ([#8281](https://github.com/parse-community/parse-server/issues/8281)) ([6c16021](https://github.com/parse-community/parse-server/commit/6c16021a1f03a70a6d9e68cb64df362d07f3b693)) + + +### BREAKING CHANGES + +* This release restricts the use of `masterKey` to localhost by default; if you are using Parse Dashboard on a different server to connect to Parse Server you need to add the IP address of the server that hosts Parse Dashboard to this option (#8281) ([6c16021](6c16021)) + +# [6.0.0-alpha.7](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.6...6.0.0-alpha.7) (2022-11-11) + + +### Features + +* Upgrade Redis 3 to 4 ([#8293](https://github.com/parse-community/parse-server/issues/8293)) ([7d622f0](https://github.com/parse-community/parse-server/commit/7d622f06a4347e0ad2cba9a4ec07d8d4fb0f67bc)) + + +### BREAKING CHANGES + +* This release upgrades to Redis 4; if you are using the Redis cache adapter with Parse Server then this is a breaking change as the Redis client options have changed; see the [Redis migration guide](https://github.com/redis/node-redis/blob/redis%404.0.0/docs/v3-to-v4.md) for more details (#8293) ([7d622f0](7d622f0)) + +# [6.0.0-alpha.6](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.5...6.0.0-alpha.6) (2022-11-10) + + +### Features + +* Remove support for MongoDB 4.0 ([#8292](https://github.com/parse-community/parse-server/issues/8292)) ([37245f6](https://github.com/parse-community/parse-server/commit/37245f62ce83516b6b95a54b850f0274ef680478)) + + +### BREAKING CHANGES + +* This release removes support for MongoDB 4.0; the new minimum supported MongoDB version is 4.2. which also removes support for the deprecated MongoDB MMAPv1 storage engine ([37245f6](37245f6)) + +# [6.0.0-alpha.5](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.4...6.0.0-alpha.5) (2022-11-10) + + +### Bug Fixes + +* Throwing error in Cloud Code Triggers `afterLogin`, `afterLogout` crashes server ([#8280](https://github.com/parse-community/parse-server/issues/8280)) ([130d290](https://github.com/parse-community/parse-server/commit/130d29074e3f763460e5685d0b9059e5a333caff)) + + +### BREAKING CHANGES + +* Throwing an error in Cloud Code Triggers `afterLogin`, `afterLogout` returns a rejected promise; in previous releases it crashed the server if you did not handle the error on the Node.js process level; consider adapting your code if your app currently handles these errors on the Node.js process level with `process.on('unhandledRejection', ...)` ([130d290](130d290)) + +# [6.0.0-alpha.4](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.3...6.0.0-alpha.4) (2022-11-10) + + +### Features + +* Remove deprecation `DEPPS2`: Config option `directAccess` defaults to true ([#8284](https://github.com/parse-community/parse-server/issues/8284)) ([f535ee6](https://github.com/parse-community/parse-server/commit/f535ee6ec2abba63f702127258ca49fa5b4e08c9)) + + +### BREAKING CHANGES + +* Config option `directAccess` defaults to true; set this to `false` in environments where multiple Parse Server instances run behind a load balancer and Parse requests within the current Node.js environment should be routed via the load balancer and distributed as HTTP requests among all instances via the `serverURL`. ([f535ee6](f535ee6)) + +# [6.0.0-alpha.3](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.2...6.0.0-alpha.3) (2022-11-10) + + +### Features + +* Remove deprecation `DEPPS4`: Remove convenience method for http request `Parse.Cloud.httpRequest` ([#8287](https://github.com/parse-community/parse-server/issues/8287)) ([2d79c08](https://github.com/parse-community/parse-server/commit/2d79c0835b6a9acaf20d5c943d9b4619bb96831c)) + + +### BREAKING CHANGES + +* The convenience method for HTTP requests `Parse.Cloud.httpRequest` is removed; use your preferred 3rd party library for making HTTP requests ([2d79c08](2d79c08)) + +# [6.0.0-alpha.2](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.1...6.0.0-alpha.2) (2022-11-10) + + +### Features + +* Improve authentication adapter interface to support multi-factor authentication (MFA), authentication challenges, and provide a more powerful interface for writing custom authentication adapters ([#8156](https://github.com/parse-community/parse-server/issues/8156)) ([5bbf9ca](https://github.com/parse-community/parse-server/commit/5bbf9cade9a527787fd1002072d4013ab5d8db2b)) + +# [6.0.0-alpha.1](https://github.com/parse-community/parse-server/compare/5.4.0-alpha.1...6.0.0-alpha.1) (2022-11-10) + + +### Bug Fixes + +* Remove Node 12 and Node 17 support ([#8279](https://github.com/parse-community/parse-server/issues/8279)) ([2546cc8](https://github.com/parse-community/parse-server/commit/2546cc8572bea6610cb9b3c7401d9afac0e3c1d6)) + + +### BREAKING CHANGES + +* This release removes Node 12 and Node 17 support ([2546cc8](2546cc8)) + +# [5.4.0-alpha.1](https://github.com/parse-community/parse-server/compare/5.3.0...5.4.0-alpha.1) (2022-10-31) + + +### Bug Fixes + +* authentication adapter app ID validation may be circumvented; this fixes a vulnerability that affects configurations which allow users to authenticate using the Parse Server authentication adapter for *Facebook* or *Spotify* and where the server-side authentication adapter configuration `appIds` is set as a string (e.g. `abc`) instead of an array of strings (e.g. `["abc"]`) ([GHSA-r657-33vp-gp22](https://github.com/parse-community/parse-server/security/advisories/GHSA-r657-33vp-gp22)) [skip release] ([#8187](https://github.com/parse-community/parse-server/issues/8187)) ([8c8ec71](https://github.com/parse-community/parse-server/commit/8c8ec715739e0f851338cfed794409ebac66c51b)) +* brute force guessing of user sensitive data via search patterns (GHSA-2m6g-crv8-p3c6) ([#8146](https://github.com/parse-community/parse-server/issues/8146)) [skip release] ([4c0c7c7](https://github.com/parse-community/parse-server/commit/4c0c7c77b76257878b9bcb05ff9de01c9d790262)) +* certificate in Apple Game Center auth adapter not validated [skip release] ([#8058](https://github.com/parse-community/parse-server/issues/8058)) ([75af9a2](https://github.com/parse-community/parse-server/commit/75af9a26cc8e9e88a33d1e452c93a0ee6e509f17)) +* graphQL query ignores condition `equalTo` with value `false` ([#8032](https://github.com/parse-community/parse-server/issues/8032)) ([7f5a15d](https://github.com/parse-community/parse-server/commit/7f5a15d5df0dfa3515e9f73709d6a49663545f9b)) +* internal indices for classes `_Idempotency` and `_Role` are not protected in defined schema ([#8121](https://github.com/parse-community/parse-server/issues/8121)) ([c16f529](https://github.com/parse-community/parse-server/commit/c16f529f74f92154401bf662f634b3c5fa45e18e)) +* invalid file request not properly handled [skip release] ([#8062](https://github.com/parse-community/parse-server/issues/8062)) ([4c9e956](https://github.com/parse-community/parse-server/commit/4c9e95674ad081f13062e8cd30b77b1962d5df57)) +* liveQuery with `containedIn` not working when object field is an array ([#8128](https://github.com/parse-community/parse-server/issues/8128)) ([1d9605b](https://github.com/parse-community/parse-server/commit/1d9605bc93009263d3811df4d4249034ba6eb8c4)) +* protected fields exposed via LiveQuery (GHSA-crrq-vr9j-fxxh) [skip release] ([#8076](https://github.com/parse-community/parse-server/issues/8076)) ([9fd4516](https://github.com/parse-community/parse-server/commit/9fd4516cde5c742f9f29dd05468b4a43a85639a6)) +* push notifications `badge` doesn't update with Installation beforeSave trigger ([#8162](https://github.com/parse-community/parse-server/issues/8162)) ([3c75c2b](https://github.com/parse-community/parse-server/commit/3c75c2ba4851fae96a8c19b11a3efde03816c9a1)) +* query aggregation pipeline cannot handle value of type `Date` when `directAccess: true` ([#8167](https://github.com/parse-community/parse-server/issues/8167)) ([e424137](https://github.com/parse-community/parse-server/commit/e4241374061caef66538de15112fb6bbafb1f5bb)) +* relation constraints in compound queries `Parse.Query.or`, `Parse.Query.and` not working ([#8203](https://github.com/parse-community/parse-server/issues/8203)) ([28f0d26](https://github.com/parse-community/parse-server/commit/28f0d2667787d2ac68726607b811d6f0ef62b9f1)) +* security upgrade undici from 5.6.0 to 5.8.0 ([#8108](https://github.com/parse-community/parse-server/issues/8108)) ([4aa016b](https://github.com/parse-community/parse-server/commit/4aa016b7322467422b9fdf05d8e29b9ecf910da7)) +* server crashes when receiving file download request with invalid byte range; this fixes a security vulnerability that allows an attacker to impact the availability of the server instance; the fix improves parsing of the range parameter to properly handle invalid range requests ([GHSA-h423-w6qv-2wj3](https://github.com/parse-community/parse-server/security/advisories/GHSA-h423-w6qv-2wj3)) [skip release] ([#8238](https://github.com/parse-community/parse-server/issues/8238)) ([c03908f](https://github.com/parse-community/parse-server/commit/c03908f74e5c9eed834874a89df6c89c1a1e849f)) +* session object properties can be updated by foreign user; this fixes a security vulnerability in which a foreign user can write to the session object of another user if the session object ID is known; the fix prevents writing to foreign session objects ([GHSA-6w4q-23cf-j9jp](https://github.com/parse-community/parse-server/security/advisories/GHSA-6w4q-23cf-j9jp)) [skip release] ([#8180](https://github.com/parse-community/parse-server/issues/8180)) ([37fed30](https://github.com/parse-community/parse-server/commit/37fed3062ccc3ef1dfd49a9fc53318e72b3e4aff)) +* sorting by non-existing value throws `INVALID_SERVER_ERROR` on Postgres ([#8157](https://github.com/parse-community/parse-server/issues/8157)) ([3b775a1](https://github.com/parse-community/parse-server/commit/3b775a1fb8a1878714e3451191438963d688f1b0)) +* updating object includes unchanged keys in client response for certain key types ([#8159](https://github.com/parse-community/parse-server/issues/8159)) ([37af1d7](https://github.com/parse-community/parse-server/commit/37af1d78fce5a15039ffe3af7b323c1f1e8582fc)) + +### Features + +* add convenience access to Parse Server configuration in Cloud Code via `Parse.Server` ([#8244](https://github.com/parse-community/parse-server/issues/8244)) ([9f11115](https://github.com/parse-community/parse-server/commit/9f111158edf7fd57a65db0c4f9244b37e58cf293)) +* add option to change the default value of the `Parse.Query.limit()` constraint ([#8152](https://github.com/parse-community/parse-server/issues/8152)) ([0388956](https://github.com/parse-community/parse-server/commit/038895680894984e569dff54bf5c7b31094f3891)) +* add support for MongoDB 6 ([#8242](https://github.com/parse-community/parse-server/issues/8242)) ([aba0081](https://github.com/parse-community/parse-server/commit/aba0081ce1a166a93de57f3928c19a05562b5cc1)) +* add support for Postgres 15 ([#8215](https://github.com/parse-community/parse-server/issues/8215)) ([2feb6c4](https://github.com/parse-community/parse-server/commit/2feb6c46080946c984daa351187fa07cd582355d)) +* liveQuery support for unsorted distance queries ([#8221](https://github.com/parse-community/parse-server/issues/8221)) ([0f763da](https://github.com/parse-community/parse-server/commit/0f763da17d646b2fec2cd980d3857e46072a8a07)) + # [5.3.0-alpha.32](https://github.com/parse-community/parse-server/compare/5.3.0-alpha.31...5.3.0-alpha.32) (2022-10-29) diff --git a/changelogs/CHANGELOG_beta.md b/changelogs/CHANGELOG_beta.md index 7384711535..2db9aed2f1 100644 --- a/changelogs/CHANGELOG_beta.md +++ b/changelogs/CHANGELOG_beta.md @@ -1,3 +1,214 @@ +# [7.0.0-beta.1](https://github.com/parse-community/parse-server/compare/6.5.0-beta.1...7.0.0-beta.1) (2024-03-19) + + +### Bug Fixes + +* CacheAdapter does not connect when using a CacheAdapter with a JSON config ([#8633](https://github.com/parse-community/parse-server/issues/8633)) ([720d24e](https://github.com/parse-community/parse-server/commit/720d24e18540da35d50957f17be878316ec30318)) +* Conditional email verification not working in some cases if `verifyUserEmails`, `preventLoginWithUnverifiedEmail` set to functions ([#8838](https://github.com/parse-community/parse-server/issues/8838)) ([8e7a6b1](https://github.com/parse-community/parse-server/commit/8e7a6b1480c0117e6c73e7adc5a6619115a04e85)) +* Deny request if master key is not set in Parse Server option `masterKeyIps` regardless of ACL and CLP ([#8957](https://github.com/parse-community/parse-server/issues/8957)) ([a7b5b38](https://github.com/parse-community/parse-server/commit/a7b5b38418cbed9be3f4a7665f25b97f592663e1)) +* Docker image not published to Docker Hub on new release ([#8905](https://github.com/parse-community/parse-server/issues/8905)) ([a2ac8d1](https://github.com/parse-community/parse-server/commit/a2ac8d133c71cd7b61e5ef59c4be915cfea85db6)) +* Docker version releases by removing arm/v6 and arm/v7 support ([#8976](https://github.com/parse-community/parse-server/issues/8976)) ([1f62dd0](https://github.com/parse-community/parse-server/commit/1f62dd0f4e107b22a387692558a042ee26ce8703)) +* GraphQL file upload fails in case of use of pointer or relation ([#8721](https://github.com/parse-community/parse-server/issues/8721)) ([1aba638](https://github.com/parse-community/parse-server/commit/1aba6382c873fb489d4a898d301e6da9fb6aa61b)) +* Improve PostgreSQL injection detection; fixes security vulnerability [GHSA-6927-3vr9-fxf2](https://github.com/parse-community/parse-server/security/advisories/GHSA-6927-3vr9-fxf2) which affects Parse Server deployments using a Postgres database ([#8961](https://github.com/parse-community/parse-server/issues/8961)) ([cbefe77](https://github.com/parse-community/parse-server/commit/cbefe770a7260b54748a058b8a7389937dc35833)) +* Incomplete user object in `verifyEmail` function if both username and email are changed ([#8889](https://github.com/parse-community/parse-server/issues/8889)) ([1eb95ae](https://github.com/parse-community/parse-server/commit/1eb95aeb41a96250e582d79a703f6adcb403c08b)) +* Parse Server option `emailVerifyTokenReuseIfValid: true` generates new token on every email verification request ([#8885](https://github.com/parse-community/parse-server/issues/8885)) ([0023ce4](https://github.com/parse-community/parse-server/commit/0023ce448a5e9423337d0e1a25648bde1156bc95)) +* Parse Server option `fileExtensions` default value rejects file extensions that are less than 3 or more than 4 characters long ([#8699](https://github.com/parse-community/parse-server/issues/8699)) ([2760381](https://github.com/parse-community/parse-server/commit/276038118377c2b22381bcd8d30337203822121b)) +* Server crashes on invalid Cloud Function or Cloud Job name; fixes security vulnerability [GHSA-6hh7-46r2-vf29](https://github.com/parse-community/parse-server/security/advisories/GHSA-6hh7-46r2-vf29) ([#9024](https://github.com/parse-community/parse-server/issues/9024)) ([9f6e342](https://github.com/parse-community/parse-server/commit/9f6e3429d3b326cf4e2994733c618d08032fac6e)) +* Server crashes when receiving an array of `Parse.Pointer` in the request body ([#8784](https://github.com/parse-community/parse-server/issues/8784)) ([66e3603](https://github.com/parse-community/parse-server/commit/66e36039d8af654cfa0284666c0ddd94975dcb52)) +* Username is `undefined` in email verification link on email change ([#8887](https://github.com/parse-community/parse-server/issues/8887)) ([e315c13](https://github.com/parse-community/parse-server/commit/e315c137bf41bedfa8f0df537f2c3f6ab45b7e60)) + +### Features + +* Add `installationId` to arguments for `verifyUserEmails`, `preventLoginWithUnverifiedEmail` ([#8836](https://github.com/parse-community/parse-server/issues/8836)) ([a22dbe1](https://github.com/parse-community/parse-server/commit/a22dbe16d5ac0090608f6caaf0ebd134925b7fd4)) +* Add `installationId`, `ip`, `resendRequest` to arguments passed to `verifyUserEmails` on verification email request ([#8873](https://github.com/parse-community/parse-server/issues/8873)) ([8adcbee](https://github.com/parse-community/parse-server/commit/8adcbee11283d3e95179ca2047e2615f52c18806)) +* Add `Parse.User` as function parameter to Parse Server options `verifyUserEmails`, `preventLoginWithUnverifiedEmail` on login ([#8850](https://github.com/parse-community/parse-server/issues/8850)) ([972f630](https://github.com/parse-community/parse-server/commit/972f6300163b3cd7d95eeb95986e8322c95f821c)) +* Add password validation via POST request for user with unverified email using master key and option `ignoreEmailVerification` ([#8895](https://github.com/parse-community/parse-server/issues/8895)) ([633a9d2](https://github.com/parse-community/parse-server/commit/633a9d25e4253e2125bc93c02ee8a37e0f5f7b83)) +* Add support for MongoDB 7 ([#8761](https://github.com/parse-community/parse-server/issues/8761)) ([3de8494](https://github.com/parse-community/parse-server/commit/3de8494a221991dfd10a74e0a2dc89576265c9b7)) +* Add support for MongoDB query comment ([#8928](https://github.com/parse-community/parse-server/issues/8928)) ([2170962](https://github.com/parse-community/parse-server/commit/2170962a50fa353ed85eda3f11dce7ee3647b087)) +* Add support for Node 20, drop support for Node 14, 16 ([#8907](https://github.com/parse-community/parse-server/issues/8907)) ([ced4872](https://github.com/parse-community/parse-server/commit/ced487246ea0ef72a8aa014991f003209b34841e)) +* Add support for Postgres 16 ([#8898](https://github.com/parse-community/parse-server/issues/8898)) ([99489b2](https://github.com/parse-community/parse-server/commit/99489b22e4f0982e6cb39992974b51aa8d3a31e4)) +* Allow `Parse.Session.current` on expired session token instead of throwing error ([#8722](https://github.com/parse-community/parse-server/issues/8722)) ([f9dde4a](https://github.com/parse-community/parse-server/commit/f9dde4a9f8a90c63f71172c9bc515b0f6c6d2e4a)) +* Deprecation DEPPS5: Config option `allowClientClassCreation` defaults to `false` ([#8849](https://github.com/parse-community/parse-server/issues/8849)) ([29624e0](https://github.com/parse-community/parse-server/commit/29624e0fae17161cd412ae58d35a195cfa286cad)) +* Deprecation DEPPS6: Authentication adapters disabled by default ([#8858](https://github.com/parse-community/parse-server/issues/8858)) ([0cf58eb](https://github.com/parse-community/parse-server/commit/0cf58eb8d60c8e5f485764e154f3214c49eee430)) +* Deprecation DEPPS7: Remove deprecated Cloud Code file trigger syntax ([#8855](https://github.com/parse-community/parse-server/issues/8855)) ([4e6a375](https://github.com/parse-community/parse-server/commit/4e6a375b5184ae0f7aa256a921eca4021c609435)) +* Deprecation DEPPS8: Parse Server option `allowExpiredAuthDataToken` defaults to `false` ([#8860](https://github.com/parse-community/parse-server/issues/8860)) ([e29845f](https://github.com/parse-community/parse-server/commit/e29845f8dacac09ce3093d75c0d92330c24389e8)) +* Deprecation DEPPS9: LiveQuery `fields` option is renamed to `keys` ([#8852](https://github.com/parse-community/parse-server/issues/8852)) ([38983e8](https://github.com/parse-community/parse-server/commit/38983e8e9b5cdbd006f311a2338103624137d013)) +* Node process exits with error code 1 on uncaught exception to allow custom uncaught exception handling ([#8894](https://github.com/parse-community/parse-server/issues/8894)) ([70c280c](https://github.com/parse-community/parse-server/commit/70c280ca578ff28b5acf92f37fbe06d42a5b34ca)) +* Switch GraphQL server from Yoga v2 to Apollo v4 ([#8959](https://github.com/parse-community/parse-server/issues/8959)) ([105ae7c](https://github.com/parse-community/parse-server/commit/105ae7c8a57d5a650b243174a80c26bf6db16e28)) +* Upgrade Parse Server Push Adapter to 5.0.2 ([#8813](https://github.com/parse-community/parse-server/issues/8813)) ([6ef1986](https://github.com/parse-community/parse-server/commit/6ef1986c03a1d84b7e11c05851e5bf9688d88740)) +* Upgrade to Parse JS SDK 5 ([#9022](https://github.com/parse-community/parse-server/issues/9022)) ([ad4aa83](https://github.com/parse-community/parse-server/commit/ad4aa83983205a0e27639f6ee6a4a5963b67e4b8)) + +### Performance Improvements + +* Improved IP validation performance for `masterKeyIPs`, `maintenanceKeyIPs` ([#8510](https://github.com/parse-community/parse-server/issues/8510)) ([b87daba](https://github.com/parse-community/parse-server/commit/b87daba0671a1b0b7b8d63bc671d665c91a04522)) + + +### BREAKING CHANGES + +* The Parse Server option `allowClientClassCreation` defaults to `false`. ([29624e0](29624e0)) +* A request using the master key will now be rejected as unauthorized if the IP from which the request originates is not set in the Parse Server option `masterKeyIps`, even if the request does not require the master key permission, for example for a public object in a public class class. ([a7b5b38](a7b5b38)) +* Node process now exits with code 1 on uncaught exceptions, enabling custom handlers that were blocked by Parse Server's default behavior of re-throwing errors. This change may lead to automatic process restarts by the environment, unlike before. ([70c280c](70c280c)) +* Authentication adapters are disabled by default; to use an authentication adapter it needs to be explicitly enabled in the Parse Server authentication adapter option `auth..enabled: true` ([0cf58eb](0cf58eb)) +* Parse Server option `allowExpiredAuthDataToken` defaults to `false`; a 3rd party authentication token will be validated every time the user tries to log in and the login will fail if the token has expired; the effect of this change may differ for different authentication adapters, depending on the token lifetime and the token refresh logic of the adapter ([e29845f](e29845f)) +* LiveQuery `fields` option is renamed to `keys` ([38983e8](38983e8)) +* Cloud Code file trigger syntax has been aligned with object trigger syntax, for example `Parse.Cloud.beforeDeleteFile'` has been changed to `Parse.Cloud.beforeDelete(Parse.File, (request) => {})'` ([4e6a375](4e6a375)) +* Removes support for Node 14 and 16 ([ced4872](ced4872)) +* Removes support for Postgres 11 and 12 ([99489b2](99489b2)) +* The `Parse.User` passed as argument if `verifyUserEmails` is set to a function is renamed from `user` to `object` for consistency with invocations of `verifyUserEmails` on signup or login; the user object is not a plain JavaScript object anymore but an instance of `Parse.User` ([8adcbee](8adcbee)) +* `Parse.Session.current()` no longer throws an error if the session token is expired, but instead returns the session token with its expiration date to allow checking its validity ([f9dde4a](f9dde4a)) +* `Parse.Query` no longer supports the BSON type `code`; although this feature was never officially documented, its removal is announced as a breaking change to protect deployments where it might be in use. ([3de8494](3de8494)) + +# [6.5.0-beta.1](https://github.com/parse-community/parse-server/compare/6.4.0...6.5.0-beta.1) (2023-11-16) + + +### Bug Fixes + +* Context not passed to Cloud Code Trigger `beforeFind` when using `Parse.Query.include` ([#8765](https://github.com/parse-community/parse-server/issues/8765)) ([7d32d89](https://github.com/parse-community/parse-server/commit/7d32d8934f3ae7af7a7d8b9cc6a829c7d73973d3)) +* Parse Server option `fileUpload.fileExtensions` fails to determine file extension if filename contains multiple dots ([#8754](https://github.com/parse-community/parse-server/issues/8754)) ([3d6d50e](https://github.com/parse-community/parse-server/commit/3d6d50e0afff18b95fb906914e2cebd3839b517a)) +* Security bump @babel/traverse from 7.20.5 to 7.23.2 ([#8777](https://github.com/parse-community/parse-server/issues/8777)) ([2d6b3d1](https://github.com/parse-community/parse-server/commit/2d6b3d18499179e99be116f25c0850d3f449509c)) +* Security upgrade graphql from 16.6.0 to 16.8.1 ([#8758](https://github.com/parse-community/parse-server/issues/8758)) ([71dfd8a](https://github.com/parse-community/parse-server/commit/71dfd8a7ece8c0dd1a66d03bb9420cfd39f4f9b1)) + +### Features + +* Add `$setOnInsert` operator to `Parse.Server.database.update` ([#8791](https://github.com/parse-community/parse-server/issues/8791)) ([f630a45](https://github.com/parse-community/parse-server/commit/f630a45aa5e87bc73a81fded061400c199b71a29)) +* Add compatibility for MongoDB Atlas Serverless and AWS Amazon DocumentDB with collation options `enableCollationCaseComparison`, `transformEmailToLowercase`, `transformUsernameToLowercase` ([#8805](https://github.com/parse-community/parse-server/issues/8805)) ([09fbeeb](https://github.com/parse-community/parse-server/commit/09fbeebba8870e7cf371fb84371a254c7b368620)) +* Add context to Cloud Code Triggers `beforeLogin` and `afterLogin` ([#8724](https://github.com/parse-community/parse-server/issues/8724)) ([a9c34ef](https://github.com/parse-community/parse-server/commit/a9c34ef1e2c78a42fb8b5fa8d569b7677c74919d)) +* Allow setting `createdAt` and `updatedAt` during `Parse.Object` creation with maintenance key ([#8696](https://github.com/parse-community/parse-server/issues/8696)) ([77bbfb3](https://github.com/parse-community/parse-server/commit/77bbfb3f186f5651c33ba152f04cff95128eaf2d)) + +# [6.4.0-beta.1](https://github.com/parse-community/parse-server/compare/6.3.0...6.4.0-beta.1) (2023-09-16) + + +### Bug Fixes + +* Parse Server option `fileUpload.fileExtensions` does not work with an array of extensions ([#8688](https://github.com/parse-community/parse-server/issues/8688)) ([6a4a00c](https://github.com/parse-community/parse-server/commit/6a4a00ca7af1163ea74b047b85cd6817366b824b)) +* Redis 4 does not reconnect after unhandled error ([#8706](https://github.com/parse-community/parse-server/issues/8706)) ([2b3d4e5](https://github.com/parse-community/parse-server/commit/2b3d4e5d3c85cd142f85af68dec51a8523548d49)) +* Remove config logging when launching Parse Server via CLI ([#8710](https://github.com/parse-community/parse-server/issues/8710)) ([ae68f0c](https://github.com/parse-community/parse-server/commit/ae68f0c31b741eeb83379c905c7ddfaa124436ec)) +* Server does not start via CLI when `auth` option is set ([#8666](https://github.com/parse-community/parse-server/issues/8666)) ([4e2000b](https://github.com/parse-community/parse-server/commit/4e2000bc563324389584ace3c090a5c1a7796a64)) + +### Features + +* Add conditional email verification via dynamic Parse Server options `verifyUserEmails`, `sendUserEmailVerification` that now accept functions ([#8425](https://github.com/parse-community/parse-server/issues/8425)) ([44acd6d](https://github.com/parse-community/parse-server/commit/44acd6d9ed157ad4842200c9d01f9c77a05fec3a)) +* Add property `Parse.Server.version` to determine current version of Parse Server in Cloud Code ([#8670](https://github.com/parse-community/parse-server/issues/8670)) ([a9d376b](https://github.com/parse-community/parse-server/commit/a9d376b61f5b07806eafbda91c4e36c322f09298)) +* Add TOTP authentication adapter ([#8457](https://github.com/parse-community/parse-server/issues/8457)) ([cc079a4](https://github.com/parse-community/parse-server/commit/cc079a40f6849a0e9bc6fdc811e8649ecb67b589)) + +### Performance Improvements + +* Improve performance of recursive pointer iterations ([#8741](https://github.com/parse-community/parse-server/issues/8741)) ([45a3ed0](https://github.com/parse-community/parse-server/commit/45a3ed0fcf2c0170607505a1550fb15896e705fd)) + +# [6.3.0-beta.1](https://github.com/parse-community/parse-server/compare/6.2.0...6.3.0-beta.1) (2023-06-10) + + +### Bug Fixes + +* Cloud Code Trigger `afterSave` executes even if not set ([#8520](https://github.com/parse-community/parse-server/issues/8520)) ([afd0515](https://github.com/parse-community/parse-server/commit/afd0515e207bd947840579d3f245980dffa6f804)) +* GridFS file storage doesn't work with certain `enableSchemaHooks` settings ([#8467](https://github.com/parse-community/parse-server/issues/8467)) ([d4cda4b](https://github.com/parse-community/parse-server/commit/d4cda4b26c9bde8c812549b8780bea1cfabdb394)) +* Inaccurate table total row count for PostgreSQL ([#8511](https://github.com/parse-community/parse-server/issues/8511)) ([0823a02](https://github.com/parse-community/parse-server/commit/0823a02fbf80bc88dc403bc47e9f5c6597ea78b4)) +* LiveQuery server is not shut down properly when `handleShutdown` is called ([#8491](https://github.com/parse-community/parse-server/issues/8491)) ([967700b](https://github.com/parse-community/parse-server/commit/967700bdbc94c74f75ba84d2b3f4b9f3fd2dca0b)) +* Rate limit feature is incompatible with Node 14 ([#8578](https://github.com/parse-community/parse-server/issues/8578)) ([f911f2c](https://github.com/parse-community/parse-server/commit/f911f2cd3a8c45cd326272dcd681532764a3761e)) +* Unnecessary log entries by `extendSessionOnUse` ([#8562](https://github.com/parse-community/parse-server/issues/8562)) ([fd6a007](https://github.com/parse-community/parse-server/commit/fd6a0077f2e5cf83d65e52172ae5a950ab0f1eae)) + +### Features + +* `extendSessionOnUse` to automatically renew Parse Sessions ([#8505](https://github.com/parse-community/parse-server/issues/8505)) ([6f885d3](https://github.com/parse-community/parse-server/commit/6f885d36b94902fdfea873fc554dee83589e6029)) +* Add new Parse Server option `preventSignupWithUnverifiedEmail` to prevent returning a user without session token on sign-up with unverified email address ([#8451](https://github.com/parse-community/parse-server/issues/8451)) ([82da308](https://github.com/parse-community/parse-server/commit/82da30842a55980aa90cb7680fbf6db37ee16dab)) +* Add option to change the log level of logs emitted by Cloud Functions ([#8530](https://github.com/parse-community/parse-server/issues/8530)) ([2caea31](https://github.com/parse-community/parse-server/commit/2caea310be412d82b04a85716bc769ccc410316d)) +* Add support for `$eq` query constraint in LiveQuery ([#8614](https://github.com/parse-community/parse-server/issues/8614)) ([656d673](https://github.com/parse-community/parse-server/commit/656d673cf5dea354e4f2b3d4dc2b29a41d311b3e)) +* Add zones for rate limiting by `ip`, `user`, `session`, `global` ([#8508](https://github.com/parse-community/parse-server/issues/8508)) ([03fba97](https://github.com/parse-community/parse-server/commit/03fba97e0549bfcaeee9f2fa4c9905dbcc91840e)) +* Allow `Parse.Object` pointers in Cloud Code arguments ([#8490](https://github.com/parse-community/parse-server/issues/8490)) ([28aeda3](https://github.com/parse-community/parse-server/commit/28aeda3f160efcbbcf85a85484a8d26567fa9761)) + +### Reverts + +* fix: Inaccurate table total row count for PostgreSQL ([6722110](https://github.com/parse-community/parse-server/commit/6722110f203bc5fdcaa68cdf091cf9e7b48d1cff)) + +# [6.1.0-beta.2](https://github.com/parse-community/parse-server/compare/6.1.0-beta.1...6.1.0-beta.2) (2023-05-01) + + +### Bug Fixes + +* LiveQuery can return incorrectly formatted date ([#8456](https://github.com/parse-community/parse-server/issues/8456)) ([4ce135a](https://github.com/parse-community/parse-server/commit/4ce135a4fe930776044bc8fd786a4e17a0144e03)) +* Nested date is incorrectly decoded as empty object `{}` when fetching a Parse Object ([#8446](https://github.com/parse-community/parse-server/issues/8446)) ([22d2446](https://github.com/parse-community/parse-server/commit/22d2446dfea2bc339affc20535d181097e152acf)) +* Parameters missing in `afterFind` trigger of authentication adapters ([#8458](https://github.com/parse-community/parse-server/issues/8458)) ([ce34747](https://github.com/parse-community/parse-server/commit/ce34747e8af54cb0b6b975da38f779a5955d2d59)) +* Rate limiting across multiple servers via Redis not working ([#8469](https://github.com/parse-community/parse-server/issues/8469)) ([d9e347d](https://github.com/parse-community/parse-server/commit/d9e347d7413f30f58ffbb8397fc8b5ae23be6ff0)) + +### Features + +* Add `afterFind` trigger to authentication adapters ([#8444](https://github.com/parse-community/parse-server/issues/8444)) ([c793bb8](https://github.com/parse-community/parse-server/commit/c793bb88e7485743c7ceb65fe419cde75833ff33)) +* Add rate limiting across multiple servers via Redis ([#8394](https://github.com/parse-community/parse-server/issues/8394)) ([34833e4](https://github.com/parse-community/parse-server/commit/34833e42eec08b812b733be78df0535ab0e096b6)) +* Allow multiple origins for header `Access-Control-Allow-Origin` ([#8517](https://github.com/parse-community/parse-server/issues/8517)) ([4f15539](https://github.com/parse-community/parse-server/commit/4f15539ac244aa2d393ac5177f7604b43f69e271)) +* Export `AuthAdapter` to make it available for extension with custom authentication adapters ([#8443](https://github.com/parse-community/parse-server/issues/8443)) ([40c1961](https://github.com/parse-community/parse-server/commit/40c196153b8efa12ae384c1c0092b2ed60a260d6)) + +# [6.1.0-beta.1](https://github.com/parse-community/parse-server/compare/6.0.0...6.1.0-beta.1) (2023-03-02) + + +### Bug Fixes + +* Security upgrade jsonwebtoken to 9.0.0 ([#8420](https://github.com/parse-community/parse-server/issues/8420)) ([f5bfe45](https://github.com/parse-community/parse-server/commit/f5bfe4571e82b2b7440d41f3cff0d49937398164)) + +### Features + +* Add option `schemaCacheTtl` for schema cache pulling as alternative to `enableSchemaHooks` ([#8436](https://github.com/parse-community/parse-server/issues/8436)) ([b3b76de](https://github.com/parse-community/parse-server/commit/b3b76de71b1d4265689d052e7837c38ec1fa4323)) +* Add Parse Server option `resetPasswordSuccessOnInvalidEmail` to choose success or error response on password reset with invalid email ([#7551](https://github.com/parse-community/parse-server/issues/7551)) ([e5d610e](https://github.com/parse-community/parse-server/commit/e5d610e5e487ddab86409409ac3d7362aba8f59b)) +* Deprecate LiveQuery `fields` option in favor of `keys` for semantic consistency ([#8388](https://github.com/parse-community/parse-server/issues/8388)) ([a49e323](https://github.com/parse-community/parse-server/commit/a49e323d5ae640bff1c6603ec37fdaddb9328dd1)) + +# [6.0.0-beta.1](https://github.com/parse-community/parse-server/compare/5.4.0...6.0.0-beta.1) (2023-01-31) + + +### Bug Fixes + +* `ParseServer.verifyServerUrl` may fail if server response headers are missing; remove unnecessary logging ([#8391](https://github.com/parse-community/parse-server/issues/8391)) ([1c37a7c](https://github.com/parse-community/parse-server/commit/1c37a7cd0715949a70b220a629071c7dab7d5e7b)) +* Cloud Code trigger `beforeSave` does not work with `Parse.Role` ([#8320](https://github.com/parse-community/parse-server/issues/8320)) ([f29d972](https://github.com/parse-community/parse-server/commit/f29d9720e9b37918fd885c97a31e34c42750e724)) +* ES6 modules do not await the import of Cloud Code files ([#8368](https://github.com/parse-community/parse-server/issues/8368)) ([a7bd180](https://github.com/parse-community/parse-server/commit/a7bd180cddd784c8735622f22e012c342ad535fb)) +* Nested objects are encoded incorrectly for MongoDB ([#8209](https://github.com/parse-community/parse-server/issues/8209)) ([1412666](https://github.com/parse-community/parse-server/commit/1412666f75829612de6fb9d7ccae35761c9b75cb)) +* Parse Server option `masterKeyIps` does not include localhost by default for IPv6 ([#8322](https://github.com/parse-community/parse-server/issues/8322)) ([ab82635](https://github.com/parse-community/parse-server/commit/ab82635b0d4cf323a07ddee51fee587b43dce95c)) +* Rate limiter may reject requests that contain a session token ([#8399](https://github.com/parse-community/parse-server/issues/8399)) ([c114dc8](https://github.com/parse-community/parse-server/commit/c114dc8831055d74187b9dfb4c9eeb558520237c)) +* Remove Node 12 and Node 17 support ([#8279](https://github.com/parse-community/parse-server/issues/8279)) ([2546cc8](https://github.com/parse-community/parse-server/commit/2546cc8572bea6610cb9b3c7401d9afac0e3c1d6)) +* Schema without class level permissions may cause error ([#8409](https://github.com/parse-community/parse-server/issues/8409)) ([aa2cd51](https://github.com/parse-community/parse-server/commit/aa2cd51b703388d925e4572e5c2b2d883c68e49c)) +* The client IP address may be determined incorrectly in some cases; this fixes a security vulnerability in which the Parse Server option `masterKeyIps` may be circumvented, see [GHSA-vm5r-c87r-pf6x](https://github.com/parse-community/parse-server/security/advisories/GHSA-vm5r-c87r-pf6x) ([#8372](https://github.com/parse-community/parse-server/issues/8372)) ([892040d](https://github.com/parse-community/parse-server/commit/892040dc2f82a3e2abe2824e4b553521b6f894de)) +* Throwing error in Cloud Code Triggers `afterLogin`, `afterLogout` crashes server ([#8280](https://github.com/parse-community/parse-server/issues/8280)) ([130d290](https://github.com/parse-community/parse-server/commit/130d29074e3f763460e5685d0b9059e5a333caff)) + +### Features + +* Access the internal scope of Parse Server using the new `maintenanceKey`; the internal scope contains unofficial and undocumented fields (prefixed with underscore `_`) which are used internally by Parse Server; you may want to manipulate these fields for out-of-band changes such as data migration or correction tasks; changes within the internal scope of Parse Server may happen at any time without notice or changelog entry, it is therefore recommended to look at the source code of Parse Server to understand the effects of manipulating internal fields before using the key; it is discouraged to use the `maintenanceKey` for routine operations in a production environment; see [access scopes](https://github.com/parse-community/parse-server#access-scopes) ([#8212](https://github.com/parse-community/parse-server/issues/8212)) ([f3bcc93](https://github.com/parse-community/parse-server/commit/f3bcc9365cd6f08b0a32c132e8e5ff6d1b650863)) +* Adapt `verifyServerUrl` for new asynchronous Parse Server start-up states ([#8366](https://github.com/parse-community/parse-server/issues/8366)) ([ffa4974](https://github.com/parse-community/parse-server/commit/ffa4974158615fbff4a2692b9db41dcb50d3f77b)) +* Add `ParseQuery.watch` to trigger LiveQuery only on update of specific fields ([#8028](https://github.com/parse-community/parse-server/issues/8028)) ([fc92faa](https://github.com/parse-community/parse-server/commit/fc92faac75107b3392eeddd916c4c5b45e3c5e0c)) +* Add Node 19 support ([#8363](https://github.com/parse-community/parse-server/issues/8363)) ([a4990dc](https://github.com/parse-community/parse-server/commit/a4990dcd29abcb4442f3c424aff482a0a116160f)) +* Add option to change the log level of the logs emitted by triggers ([#8328](https://github.com/parse-community/parse-server/issues/8328)) ([8f3b694](https://github.com/parse-community/parse-server/commit/8f3b694e39d4a966567e50dbea4d62e954fa5c06)) +* Add request rate limiter based on IP address ([#8174](https://github.com/parse-community/parse-server/issues/8174)) ([6c79f6a](https://github.com/parse-community/parse-server/commit/6c79f6a69e25e47846e3b0685d6bdfd6b91086b1)) +* Asynchronous initialization of Parse Server ([#8232](https://github.com/parse-community/parse-server/issues/8232)) ([99fcf45](https://github.com/parse-community/parse-server/commit/99fcf45e55c368de2345b0c4d780e70e0adf0e15)) +* Improve authentication adapter interface to support multi-factor authentication (MFA), authentication challenges, and provide a more powerful interface for writing custom authentication adapters ([#8156](https://github.com/parse-community/parse-server/issues/8156)) ([5bbf9ca](https://github.com/parse-community/parse-server/commit/5bbf9cade9a527787fd1002072d4013ab5d8db2b)) +* Reduce Docker image size by improving stages ([#8359](https://github.com/parse-community/parse-server/issues/8359)) ([40810b4](https://github.com/parse-community/parse-server/commit/40810b48ebde8b1f21d2448a3a4de0585b1b5e34)) +* Remove deprecation `DEPPS1`: Native MongoDB syntax in aggregation pipeline ([#8362](https://github.com/parse-community/parse-server/issues/8362)) ([d0d30c4](https://github.com/parse-community/parse-server/commit/d0d30c4f1394f563724644a8fc81734be538a2c0)) +* Remove deprecation `DEPPS2`: Config option `directAccess` defaults to true ([#8284](https://github.com/parse-community/parse-server/issues/8284)) ([f535ee6](https://github.com/parse-community/parse-server/commit/f535ee6ec2abba63f702127258ca49fa5b4e08c9)) +* Remove deprecation `DEPPS3`: Config option `enforcePrivateUsers` defaults to `true` ([#8283](https://github.com/parse-community/parse-server/issues/8283)) ([ed499e3](https://github.com/parse-community/parse-server/commit/ed499e32a21bab9a874a9e5367dc71248ce836c4)) +* Remove deprecation `DEPPS4`: Remove convenience method for http request `Parse.Cloud.httpRequest` ([#8287](https://github.com/parse-community/parse-server/issues/8287)) ([2d79c08](https://github.com/parse-community/parse-server/commit/2d79c0835b6a9acaf20d5c943d9b4619bb96831c)) +* Remove support for MongoDB 4.0 ([#8292](https://github.com/parse-community/parse-server/issues/8292)) ([37245f6](https://github.com/parse-community/parse-server/commit/37245f62ce83516b6b95a54b850f0274ef680478)) +* Restrict use of `masterKey` to localhost by default ([#8281](https://github.com/parse-community/parse-server/issues/8281)) ([6c16021](https://github.com/parse-community/parse-server/commit/6c16021a1f03a70a6d9e68cb64df362d07f3b693)) +* Upgrade Node Package Manager lock file `package-lock.json` to version 2 ([#8285](https://github.com/parse-community/parse-server/issues/8285)) ([ee72467](https://github.com/parse-community/parse-server/commit/ee7246733d63e4bda20401f7b00262ff03299f20)) +* Upgrade Redis 3 to 4 ([#8293](https://github.com/parse-community/parse-server/issues/8293)) ([7d622f0](https://github.com/parse-community/parse-server/commit/7d622f06a4347e0ad2cba9a4ec07d8d4fb0f67bc)) +* Upgrade Redis 3 to 4 for LiveQuery ([#8333](https://github.com/parse-community/parse-server/issues/8333)) ([b2761fb](https://github.com/parse-community/parse-server/commit/b2761fb3786b519d9bbcf35be54309d2d35da1a9)) +* Upgrade to Parse JavaScript SDK 4 ([#8332](https://github.com/parse-community/parse-server/issues/8332)) ([9092874](https://github.com/parse-community/parse-server/commit/9092874a9a482a24dfdce1dce56615702999d6b8)) +* Write log entry when request with master key is rejected as outside of `masterKeyIps` ([#8350](https://github.com/parse-community/parse-server/issues/8350)) ([e22b73d](https://github.com/parse-community/parse-server/commit/e22b73d4b700c8ff745aa81726c6680082294b45)) + + +### BREAKING CHANGES + +* The Docker image does not contain the git dependency anymore; if you have been using git as a transitive dependency it now needs to be explicitly installed in your Docker file, for example with `RUN apk --no-cache add git` (#8359) ([40810b4](40810b4)) +* Fields in the internal scope of Parse Server (prefixed with underscore `_`) are only returned using the new `maintenanceKey`; previously the `masterKey` allowed reading of internal fields; see [access scopes](https://github.com/parse-community/parse-server#access-scopes) for a comparison of the keys' access permissions (#8212) ([f3bcc93](f3bcc93)) +* The method `ParseServer.verifyServerUrl` now returns a promise instead of a callback. ([ffa4974](ffa4974)) +* The MongoDB aggregation pipeline requires native MongoDB syntax instead of the custom Parse Server syntax; for example pipeline stage names require a leading dollar sign like `$match` and the MongoDB document ID is referenced using `_id` instead of `objectId` (#8362) ([d0d30c4](d0d30c4)) +* The mechanism to determine the client IP address has been rewritten; to correctly determine the IP address it is now required to set the Parse Server option `trustProxy` accordingly if Parse Server runs behind a proxy server, see the express framework's [trust proxy](https://expressjs.com/en/guide/behind-proxies.html) setting (#8372) ([892040d](892040d)) +* The Node Package Manager lock file `package-lock.json` is upgraded to version 2; while it is backwards with version 1 for the npm installer, consider this if you run any non-npm analysis tools that use the lock file (#8285) ([ee72467](ee72467)) +* This release introduces the asynchronous initialization of Parse Server to prevent mounting Parse Server before being ready to receive request; it changes how Parse Server is imported, initialized and started; it also removes the callback `serverStartComplete`; see the [Parse Server 6 migration guide](https://github.com/parse-community/parse-server/blob/alpha/6.0.0.md) for more details (#8232) ([99fcf45](99fcf45)) +* Nested objects are now properly stored in the database using JSON serialization; previously, due to a bug only top-level objects were serialized, but nested objects were saved as raw JSON; for example, a nested `Date` object was saved as a JSON object like `{ "__type": "Date", "iso": "2020-01-01T00:00:00.000Z" }` instead of its serialized representation `2020-01-01T00:00:00.000Z` (#8209) ([1412666](1412666)) +* The Parse Server option `enforcePrivateUsers` is set to `true` by default; in previous releases this option defaults to `false`; this change improves the default security configuration of Parse Server (#8283) ([ed499e3](ed499e3)) +* This release restricts the use of `masterKey` to localhost by default; if you are using Parse Dashboard on a different server to connect to Parse Server you need to add the IP address of the server that hosts Parse Dashboard to this option (#8281) ([6c16021](6c16021)) +* This release upgrades to Redis 4; if you are using the Redis cache adapter with Parse Server then this is a breaking change as the Redis client options have changed; see the [Redis migration guide](https://github.com/redis/node-redis/blob/redis%404.0.0/docs/v3-to-v4.md) for more details (#8293) ([7d622f0](7d622f0)) +* This release removes support for MongoDB 4.0; the new minimum supported MongoDB version is 4.2. which also removes support for the deprecated MongoDB MMAPv1 storage engine ([37245f6](37245f6)) +* Throwing an error in Cloud Code Triggers `afterLogin`, `afterLogout` returns a rejected promise; in previous releases it crashed the server if you did not handle the error on the Node.js process level; consider adapting your code if your app currently handles these errors on the Node.js process level with `process.on('unhandledRejection', ...)` ([130d290](130d290)) +* Config option `directAccess` defaults to true; set this to `false` in environments where multiple Parse Server instances run behind a load balancer and Parse requests within the current Node.js environment should be routed via the load balancer and distributed as HTTP requests among all instances via the `serverURL`. ([f535ee6](f535ee6)) +* The convenience method for HTTP requests `Parse.Cloud.httpRequest` is removed; use your preferred 3rd party library for making HTTP requests ([2d79c08](2d79c08)) +* This release removes Node 12 and Node 17 support ([2546cc8](2546cc8)) + # [5.4.0-beta.1](https://github.com/parse-community/parse-server/compare/5.3.0...5.4.0-beta.1) (2022-10-29) diff --git a/changelogs/CHANGELOG_release.md b/changelogs/CHANGELOG_release.md index 547819d7cb..f0bbcd36d9 100644 --- a/changelogs/CHANGELOG_release.md +++ b/changelogs/CHANGELOG_release.md @@ -1,3 +1,224 @@ +# [7.0.0](https://github.com/parse-community/parse-server/compare/6.4.0...7.0.0) (2024-03-19) + + +### Bug Fixes + +* CacheAdapter does not connect when using a CacheAdapter with a JSON config ([#8633](https://github.com/parse-community/parse-server/issues/8633)) ([720d24e](https://github.com/parse-community/parse-server/commit/720d24e18540da35d50957f17be878316ec30318)) +* Conditional email verification not working in some cases if `verifyUserEmails`, `preventLoginWithUnverifiedEmail` set to functions ([#8838](https://github.com/parse-community/parse-server/issues/8838)) ([8e7a6b1](https://github.com/parse-community/parse-server/commit/8e7a6b1480c0117e6c73e7adc5a6619115a04e85)) +* Context not passed to Cloud Code Trigger `beforeFind` when using `Parse.Query.include` ([#8765](https://github.com/parse-community/parse-server/issues/8765)) ([7d32d89](https://github.com/parse-community/parse-server/commit/7d32d8934f3ae7af7a7d8b9cc6a829c7d73973d3)) +* Deny request if master key is not set in Parse Server option `masterKeyIps` regardless of ACL and CLP ([#8957](https://github.com/parse-community/parse-server/issues/8957)) ([a7b5b38](https://github.com/parse-community/parse-server/commit/a7b5b38418cbed9be3f4a7665f25b97f592663e1)) +* Docker image not published to Docker Hub on new release ([#8905](https://github.com/parse-community/parse-server/issues/8905)) ([a2ac8d1](https://github.com/parse-community/parse-server/commit/a2ac8d133c71cd7b61e5ef59c4be915cfea85db6)) +* Docker version releases by removing arm/v6 and arm/v7 support ([#8976](https://github.com/parse-community/parse-server/issues/8976)) ([1f62dd0](https://github.com/parse-community/parse-server/commit/1f62dd0f4e107b22a387692558a042ee26ce8703)) +* GraphQL file upload fails in case of use of pointer or relation ([#8721](https://github.com/parse-community/parse-server/issues/8721)) ([1aba638](https://github.com/parse-community/parse-server/commit/1aba6382c873fb489d4a898d301e6da9fb6aa61b)) +* Improve PostgreSQL injection detection; fixes security vulnerability [GHSA-6927-3vr9-fxf2](https://github.com/parse-community/parse-server/security/advisories/GHSA-6927-3vr9-fxf2) which affects Parse Server deployments using a Postgres database ([#8961](https://github.com/parse-community/parse-server/issues/8961)) ([cbefe77](https://github.com/parse-community/parse-server/commit/cbefe770a7260b54748a058b8a7389937dc35833)) +* Incomplete user object in `verifyEmail` function if both username and email are changed ([#8889](https://github.com/parse-community/parse-server/issues/8889)) ([1eb95ae](https://github.com/parse-community/parse-server/commit/1eb95aeb41a96250e582d79a703f6adcb403c08b)) +* Parse Server option `emailVerifyTokenReuseIfValid: true` generates new token on every email verification request ([#8885](https://github.com/parse-community/parse-server/issues/8885)) ([0023ce4](https://github.com/parse-community/parse-server/commit/0023ce448a5e9423337d0e1a25648bde1156bc95)) +* Parse Server option `fileExtensions` default value rejects file extensions that are less than 3 or more than 4 characters long ([#8699](https://github.com/parse-community/parse-server/issues/8699)) ([2760381](https://github.com/parse-community/parse-server/commit/276038118377c2b22381bcd8d30337203822121b)) +* Parse Server option `fileUpload.fileExtensions` fails to determine file extension if filename contains multiple dots ([#8754](https://github.com/parse-community/parse-server/issues/8754)) ([3d6d50e](https://github.com/parse-community/parse-server/commit/3d6d50e0afff18b95fb906914e2cebd3839b517a)) +* Security bump @babel/traverse from 7.20.5 to 7.23.2 ([#8777](https://github.com/parse-community/parse-server/issues/8777)) ([2d6b3d1](https://github.com/parse-community/parse-server/commit/2d6b3d18499179e99be116f25c0850d3f449509c)) +* Security upgrade graphql from 16.6.0 to 16.8.1 ([#8758](https://github.com/parse-community/parse-server/issues/8758)) ([71dfd8a](https://github.com/parse-community/parse-server/commit/71dfd8a7ece8c0dd1a66d03bb9420cfd39f4f9b1)) +* Server crashes on invalid Cloud Function or Cloud Job name; fixes security vulnerability [GHSA-6hh7-46r2-vf29](https://github.com/parse-community/parse-server/security/advisories/GHSA-6hh7-46r2-vf29) ([#9024](https://github.com/parse-community/parse-server/issues/9024)) ([9f6e342](https://github.com/parse-community/parse-server/commit/9f6e3429d3b326cf4e2994733c618d08032fac6e)) +* Server crashes when receiving an array of `Parse.Pointer` in the request body ([#8784](https://github.com/parse-community/parse-server/issues/8784)) ([66e3603](https://github.com/parse-community/parse-server/commit/66e36039d8af654cfa0284666c0ddd94975dcb52)) +* Username is `undefined` in email verification link on email change ([#8887](https://github.com/parse-community/parse-server/issues/8887)) ([e315c13](https://github.com/parse-community/parse-server/commit/e315c137bf41bedfa8f0df537f2c3f6ab45b7e60)) + +### Features + +* Add `$setOnInsert` operator to `Parse.Server.database.update` ([#8791](https://github.com/parse-community/parse-server/issues/8791)) ([f630a45](https://github.com/parse-community/parse-server/commit/f630a45aa5e87bc73a81fded061400c199b71a29)) +* Add `installationId` to arguments for `verifyUserEmails`, `preventLoginWithUnverifiedEmail` ([#8836](https://github.com/parse-community/parse-server/issues/8836)) ([a22dbe1](https://github.com/parse-community/parse-server/commit/a22dbe16d5ac0090608f6caaf0ebd134925b7fd4)) +* Add `installationId`, `ip`, `resendRequest` to arguments passed to `verifyUserEmails` on verification email request ([#8873](https://github.com/parse-community/parse-server/issues/8873)) ([8adcbee](https://github.com/parse-community/parse-server/commit/8adcbee11283d3e95179ca2047e2615f52c18806)) +* Add `Parse.User` as function parameter to Parse Server options `verifyUserEmails`, `preventLoginWithUnverifiedEmail` on login ([#8850](https://github.com/parse-community/parse-server/issues/8850)) ([972f630](https://github.com/parse-community/parse-server/commit/972f6300163b3cd7d95eeb95986e8322c95f821c)) +* Add compatibility for MongoDB Atlas Serverless and AWS Amazon DocumentDB with collation options `enableCollationCaseComparison`, `transformEmailToLowercase`, `transformUsernameToLowercase` ([#8805](https://github.com/parse-community/parse-server/issues/8805)) ([09fbeeb](https://github.com/parse-community/parse-server/commit/09fbeebba8870e7cf371fb84371a254c7b368620)) +* Add context to Cloud Code Triggers `beforeLogin` and `afterLogin` ([#8724](https://github.com/parse-community/parse-server/issues/8724)) ([a9c34ef](https://github.com/parse-community/parse-server/commit/a9c34ef1e2c78a42fb8b5fa8d569b7677c74919d)) +* Add password validation via POST request for user with unverified email using master key and option `ignoreEmailVerification` ([#8895](https://github.com/parse-community/parse-server/issues/8895)) ([633a9d2](https://github.com/parse-community/parse-server/commit/633a9d25e4253e2125bc93c02ee8a37e0f5f7b83)) +* Add support for MongoDB 7 ([#8761](https://github.com/parse-community/parse-server/issues/8761)) ([3de8494](https://github.com/parse-community/parse-server/commit/3de8494a221991dfd10a74e0a2dc89576265c9b7)) +* Add support for MongoDB query comment ([#8928](https://github.com/parse-community/parse-server/issues/8928)) ([2170962](https://github.com/parse-community/parse-server/commit/2170962a50fa353ed85eda3f11dce7ee3647b087)) +* Add support for Node 20, drop support for Node 14, 16 ([#8907](https://github.com/parse-community/parse-server/issues/8907)) ([ced4872](https://github.com/parse-community/parse-server/commit/ced487246ea0ef72a8aa014991f003209b34841e)) +* Add support for Postgres 16 ([#8898](https://github.com/parse-community/parse-server/issues/8898)) ([99489b2](https://github.com/parse-community/parse-server/commit/99489b22e4f0982e6cb39992974b51aa8d3a31e4)) +* Allow `Parse.Session.current` on expired session token instead of throwing error ([#8722](https://github.com/parse-community/parse-server/issues/8722)) ([f9dde4a](https://github.com/parse-community/parse-server/commit/f9dde4a9f8a90c63f71172c9bc515b0f6c6d2e4a)) +* Allow setting `createdAt` and `updatedAt` during `Parse.Object` creation with maintenance key ([#8696](https://github.com/parse-community/parse-server/issues/8696)) ([77bbfb3](https://github.com/parse-community/parse-server/commit/77bbfb3f186f5651c33ba152f04cff95128eaf2d)) +* Deprecation DEPPS5: Config option `allowClientClassCreation` defaults to `false` ([#8849](https://github.com/parse-community/parse-server/issues/8849)) ([29624e0](https://github.com/parse-community/parse-server/commit/29624e0fae17161cd412ae58d35a195cfa286cad)) +* Deprecation DEPPS6: Authentication adapters disabled by default ([#8858](https://github.com/parse-community/parse-server/issues/8858)) ([0cf58eb](https://github.com/parse-community/parse-server/commit/0cf58eb8d60c8e5f485764e154f3214c49eee430)) +* Deprecation DEPPS7: Remove deprecated Cloud Code file trigger syntax ([#8855](https://github.com/parse-community/parse-server/issues/8855)) ([4e6a375](https://github.com/parse-community/parse-server/commit/4e6a375b5184ae0f7aa256a921eca4021c609435)) +* Deprecation DEPPS8: Parse Server option `allowExpiredAuthDataToken` defaults to `false` ([#8860](https://github.com/parse-community/parse-server/issues/8860)) ([e29845f](https://github.com/parse-community/parse-server/commit/e29845f8dacac09ce3093d75c0d92330c24389e8)) +* Deprecation DEPPS9: LiveQuery `fields` option is renamed to `keys` ([#8852](https://github.com/parse-community/parse-server/issues/8852)) ([38983e8](https://github.com/parse-community/parse-server/commit/38983e8e9b5cdbd006f311a2338103624137d013)) +* Node process exits with error code 1 on uncaught exception to allow custom uncaught exception handling ([#8894](https://github.com/parse-community/parse-server/issues/8894)) ([70c280c](https://github.com/parse-community/parse-server/commit/70c280ca578ff28b5acf92f37fbe06d42a5b34ca)) +* Switch GraphQL server from Yoga v2 to Apollo v4 ([#8959](https://github.com/parse-community/parse-server/issues/8959)) ([105ae7c](https://github.com/parse-community/parse-server/commit/105ae7c8a57d5a650b243174a80c26bf6db16e28)) +* Upgrade Parse Server Push Adapter to 5.0.2 ([#8813](https://github.com/parse-community/parse-server/issues/8813)) ([6ef1986](https://github.com/parse-community/parse-server/commit/6ef1986c03a1d84b7e11c05851e5bf9688d88740)) +* Upgrade to Parse JS SDK 5 ([#9022](https://github.com/parse-community/parse-server/issues/9022)) ([ad4aa83](https://github.com/parse-community/parse-server/commit/ad4aa83983205a0e27639f6ee6a4a5963b67e4b8)) + +### Performance Improvements + +* Improved IP validation performance for `masterKeyIPs`, `maintenanceKeyIPs` ([#8510](https://github.com/parse-community/parse-server/issues/8510)) ([b87daba](https://github.com/parse-community/parse-server/commit/b87daba0671a1b0b7b8d63bc671d665c91a04522)) + + +### BREAKING CHANGES + +* The Parse Server option `allowClientClassCreation` defaults to `false`. ([29624e0](29624e0)) +* A request using the master key will now be rejected as unauthorized if the IP from which the request originates is not set in the Parse Server option `masterKeyIps`, even if the request does not require the master key permission, for example for a public object in a public class class. ([a7b5b38](a7b5b38)) +* Node process now exits with code 1 on uncaught exceptions, enabling custom handlers that were blocked by Parse Server's default behavior of re-throwing errors. This change may lead to automatic process restarts by the environment, unlike before. ([70c280c](70c280c)) +* Authentication adapters are disabled by default; to use an authentication adapter it needs to be explicitly enabled in the Parse Server authentication adapter option `auth..enabled: true` ([0cf58eb](0cf58eb)) +* Parse Server option `allowExpiredAuthDataToken` defaults to `false`; a 3rd party authentication token will be validated every time the user tries to log in and the login will fail if the token has expired; the effect of this change may differ for different authentication adapters, depending on the token lifetime and the token refresh logic of the adapter ([e29845f](e29845f)) +* LiveQuery `fields` option is renamed to `keys` ([38983e8](38983e8)) +* Cloud Code file trigger syntax has been aligned with object trigger syntax, for example `Parse.Cloud.beforeDeleteFile'` has been changed to `Parse.Cloud.beforeDelete(Parse.File, (request) => {})'` ([4e6a375](4e6a375)) +* Removes support for Node 14 and 16 ([ced4872](ced4872)) +* Removes support for Postgres 11 and 12 ([99489b2](99489b2)) +* The `Parse.User` passed as argument if `verifyUserEmails` is set to a function is renamed from `user` to `object` for consistency with invocations of `verifyUserEmails` on signup or login; the user object is not a plain JavaScript object anymore but an instance of `Parse.User` ([8adcbee](8adcbee)) +* `Parse.Session.current()` no longer throws an error if the session token is expired, but instead returns the session token with its expiration date to allow checking its validity ([f9dde4a](f9dde4a)) +* `Parse.Query` no longer supports the BSON type `code`; although this feature was never officially documented, its removal is announced as a breaking change to protect deployments where it might be in use. ([3de8494](3de8494)) + +# [6.4.0](https://github.com/parse-community/parse-server/compare/6.3.1...6.4.0) (2023-11-16) + + +### Bug Fixes + +* Parse Server option `fileUpload.fileExtensions` does not work with an array of extensions ([#8688](https://github.com/parse-community/parse-server/issues/8688)) ([6a4a00c](https://github.com/parse-community/parse-server/commit/6a4a00ca7af1163ea74b047b85cd6817366b824b)) +* Redis 4 does not reconnect after unhandled error ([#8706](https://github.com/parse-community/parse-server/issues/8706)) ([2b3d4e5](https://github.com/parse-community/parse-server/commit/2b3d4e5d3c85cd142f85af68dec51a8523548d49)) +* Remove config logging when launching Parse Server via CLI ([#8710](https://github.com/parse-community/parse-server/issues/8710)) ([ae68f0c](https://github.com/parse-community/parse-server/commit/ae68f0c31b741eeb83379c905c7ddfaa124436ec)) +* Server does not start via CLI when `auth` option is set ([#8666](https://github.com/parse-community/parse-server/issues/8666)) ([4e2000b](https://github.com/parse-community/parse-server/commit/4e2000bc563324389584ace3c090a5c1a7796a64)) + +### Features + +* Add conditional email verification via dynamic Parse Server options `verifyUserEmails`, `sendUserEmailVerification` that now accept functions ([#8425](https://github.com/parse-community/parse-server/issues/8425)) ([44acd6d](https://github.com/parse-community/parse-server/commit/44acd6d9ed157ad4842200c9d01f9c77a05fec3a)) +* Add property `Parse.Server.version` to determine current version of Parse Server in Cloud Code ([#8670](https://github.com/parse-community/parse-server/issues/8670)) ([a9d376b](https://github.com/parse-community/parse-server/commit/a9d376b61f5b07806eafbda91c4e36c322f09298)) +* Add TOTP authentication adapter ([#8457](https://github.com/parse-community/parse-server/issues/8457)) ([cc079a4](https://github.com/parse-community/parse-server/commit/cc079a40f6849a0e9bc6fdc811e8649ecb67b589)) + +### Performance Improvements + +* Improve performance of recursive pointer iterations ([#8741](https://github.com/parse-community/parse-server/issues/8741)) ([45a3ed0](https://github.com/parse-community/parse-server/commit/45a3ed0fcf2c0170607505a1550fb15896e705fd)) + +## [6.3.1](https://github.com/parse-community/parse-server/compare/6.3.0...6.3.1) (2023-10-20) + + +### Bug Fixes + +* Server crash when uploading file without extension; fixes security vulnerability [GHSA-792q-q67h-w579](https://github.com/parse-community/parse-server/security/advisories/GHSA-792q-q67h-w579) ([#8781](https://github.com/parse-community/parse-server/issues/8781)) ([fd86278](https://github.com/parse-community/parse-server/commit/fd86278919556d3682e7e2c856dfccd5beffbfc0)) + +# [6.3.0](https://github.com/parse-community/parse-server/compare/6.2.2...6.3.0) (2023-09-16) + + +### Bug Fixes + +* Cloud Code Trigger `afterSave` executes even if not set ([#8520](https://github.com/parse-community/parse-server/issues/8520)) ([afd0515](https://github.com/parse-community/parse-server/commit/afd0515e207bd947840579d3f245980dffa6f804)) +* GridFS file storage doesn't work with certain `enableSchemaHooks` settings ([#8467](https://github.com/parse-community/parse-server/issues/8467)) ([d4cda4b](https://github.com/parse-community/parse-server/commit/d4cda4b26c9bde8c812549b8780bea1cfabdb394)) +* Inaccurate table total row count for PostgreSQL ([#8511](https://github.com/parse-community/parse-server/issues/8511)) ([0823a02](https://github.com/parse-community/parse-server/commit/0823a02fbf80bc88dc403bc47e9f5c6597ea78b4)) +* LiveQuery server is not shut down properly when `handleShutdown` is called ([#8491](https://github.com/parse-community/parse-server/issues/8491)) ([967700b](https://github.com/parse-community/parse-server/commit/967700bdbc94c74f75ba84d2b3f4b9f3fd2dca0b)) +* Rate limit feature is incompatible with Node 14 ([#8578](https://github.com/parse-community/parse-server/issues/8578)) ([f911f2c](https://github.com/parse-community/parse-server/commit/f911f2cd3a8c45cd326272dcd681532764a3761e)) +* Unnecessary log entries by `extendSessionOnUse` ([#8562](https://github.com/parse-community/parse-server/issues/8562)) ([fd6a007](https://github.com/parse-community/parse-server/commit/fd6a0077f2e5cf83d65e52172ae5a950ab0f1eae)) + +### Features + +* `extendSessionOnUse` to automatically renew Parse Sessions ([#8505](https://github.com/parse-community/parse-server/issues/8505)) ([6f885d3](https://github.com/parse-community/parse-server/commit/6f885d36b94902fdfea873fc554dee83589e6029)) +* Add new Parse Server option `preventSignupWithUnverifiedEmail` to prevent returning a user without session token on sign-up with unverified email address ([#8451](https://github.com/parse-community/parse-server/issues/8451)) ([82da308](https://github.com/parse-community/parse-server/commit/82da30842a55980aa90cb7680fbf6db37ee16dab)) +* Add option to change the log level of logs emitted by Cloud Functions ([#8530](https://github.com/parse-community/parse-server/issues/8530)) ([2caea31](https://github.com/parse-community/parse-server/commit/2caea310be412d82b04a85716bc769ccc410316d)) +* Add support for `$eq` query constraint in LiveQuery ([#8614](https://github.com/parse-community/parse-server/issues/8614)) ([656d673](https://github.com/parse-community/parse-server/commit/656d673cf5dea354e4f2b3d4dc2b29a41d311b3e)) +* Add zones for rate limiting by `ip`, `user`, `session`, `global` ([#8508](https://github.com/parse-community/parse-server/issues/8508)) ([03fba97](https://github.com/parse-community/parse-server/commit/03fba97e0549bfcaeee9f2fa4c9905dbcc91840e)) +* Allow `Parse.Object` pointers in Cloud Code arguments ([#8490](https://github.com/parse-community/parse-server/issues/8490)) ([28aeda3](https://github.com/parse-community/parse-server/commit/28aeda3f160efcbbcf85a85484a8d26567fa9761)) + +### Reverts + +* fix: Inaccurate table total row count for PostgreSQL ([6722110](https://github.com/parse-community/parse-server/commit/6722110f203bc5fdcaa68cdf091cf9e7b48d1cff)) + +## [6.2.2](https://github.com/parse-community/parse-server/compare/6.2.1...6.2.2) (2023-09-04) + + +### Bug Fixes + +* Parse Pointer allows to access internal Parse Server classes and circumvent `beforeFind` query trigger; fixes security vulnerability [GHSA-fcv6-fg5r-jm9q](https://github.com/parse-community/parse-server/security/advisories/GHSA-fcv6-fg5r-jm9q) ([be4c7e2](https://github.com/parse-community/parse-server/commit/be4c7e23c63a2fb690685665cebed0de26be05c5)) + +## [6.2.1](https://github.com/parse-community/parse-server/compare/6.2.0...6.2.1) (2023-06-28) + + +### Bug Fixes + +* Remote code execution via MongoDB BSON parser through prototype pollution; fixes security vulnerability [GHSA-462x-c3jw-7vr6](https://github.com/parse-community/parse-server/security/advisories/GHSA-462x-c3jw-7vr6) ([#8674](https://github.com/parse-community/parse-server/issues/8674)) ([3dd99dd](https://github.com/parse-community/parse-server/commit/3dd99dd80e27e5e1d99b42844180546d90c7aa90)) + +# [6.2.0](https://github.com/parse-community/parse-server/compare/6.1.0...6.2.0) (2023-05-20) + + +### Features + +* Add new Parse Server option `fileUpload.fileExtensions` to restrict file upload by file extension; this fixes a security vulnerability in which a phishing attack could be performed using an uploaded HTML file; by default the new option only allows file extensions matching the regex pattern `^[^hH][^tT][^mM][^lL]?$`, which excludes HTML files; if your app currently depends on uploading files with HTML file extensions then this may be a breaking change and you could allow HTML file upload by setting the option to `['.*']` ([#8538](https://github.com/parse-community/parse-server/issues/8538)) ([a318e7b](https://github.com/parse-community/parse-server/commit/a318e7bbafcf7a3425b0a1b3c2dd30f526b4b6f9)) + +# [6.1.0](https://github.com/parse-community/parse-server/compare/6.0.0...6.1.0) (2023-05-01) + + +### Bug Fixes + +* LiveQuery can return incorrectly formatted date ([#8456](https://github.com/parse-community/parse-server/issues/8456)) ([4ce135a](https://github.com/parse-community/parse-server/commit/4ce135a4fe930776044bc8fd786a4e17a0144e03)) +* Nested date is incorrectly decoded as empty object `{}` when fetching a Parse Object ([#8446](https://github.com/parse-community/parse-server/issues/8446)) ([22d2446](https://github.com/parse-community/parse-server/commit/22d2446dfea2bc339affc20535d181097e152acf)) +* Parameters missing in `afterFind` trigger of authentication adapters ([#8458](https://github.com/parse-community/parse-server/issues/8458)) ([ce34747](https://github.com/parse-community/parse-server/commit/ce34747e8af54cb0b6b975da38f779a5955d2d59)) +* Rate limiting across multiple servers via Redis not working ([#8469](https://github.com/parse-community/parse-server/issues/8469)) ([d9e347d](https://github.com/parse-community/parse-server/commit/d9e347d7413f30f58ffbb8397fc8b5ae23be6ff0)) +* Security upgrade jsonwebtoken to 9.0.0 ([#8420](https://github.com/parse-community/parse-server/issues/8420)) ([f5bfe45](https://github.com/parse-community/parse-server/commit/f5bfe4571e82b2b7440d41f3cff0d49937398164)) + +### Features + +* Add `afterFind` trigger to authentication adapters ([#8444](https://github.com/parse-community/parse-server/issues/8444)) ([c793bb8](https://github.com/parse-community/parse-server/commit/c793bb88e7485743c7ceb65fe419cde75833ff33)) +* Add option `schemaCacheTtl` for schema cache pulling as alternative to `enableSchemaHooks` ([#8436](https://github.com/parse-community/parse-server/issues/8436)) ([b3b76de](https://github.com/parse-community/parse-server/commit/b3b76de71b1d4265689d052e7837c38ec1fa4323)) +* Add Parse Server option `resetPasswordSuccessOnInvalidEmail` to choose success or error response on password reset with invalid email ([#7551](https://github.com/parse-community/parse-server/issues/7551)) ([e5d610e](https://github.com/parse-community/parse-server/commit/e5d610e5e487ddab86409409ac3d7362aba8f59b)) +* Add rate limiting across multiple servers via Redis ([#8394](https://github.com/parse-community/parse-server/issues/8394)) ([34833e4](https://github.com/parse-community/parse-server/commit/34833e42eec08b812b733be78df0535ab0e096b6)) +* Allow multiple origins for header `Access-Control-Allow-Origin` ([#8517](https://github.com/parse-community/parse-server/issues/8517)) ([4f15539](https://github.com/parse-community/parse-server/commit/4f15539ac244aa2d393ac5177f7604b43f69e271)) +* Deprecate LiveQuery `fields` option in favor of `keys` for semantic consistency ([#8388](https://github.com/parse-community/parse-server/issues/8388)) ([a49e323](https://github.com/parse-community/parse-server/commit/a49e323d5ae640bff1c6603ec37fdaddb9328dd1)) +* Export `AuthAdapter` to make it available for extension with custom authentication adapters ([#8443](https://github.com/parse-community/parse-server/issues/8443)) ([40c1961](https://github.com/parse-community/parse-server/commit/40c196153b8efa12ae384c1c0092b2ed60a260d6)) + +# [6.0.0](https://github.com/parse-community/parse-server/compare/5.4.0...6.0.0) (2023-01-31) + + +### Bug Fixes + +* `ParseServer.verifyServerUrl` may fail if server response headers are missing; remove unnecessary logging ([#8391](https://github.com/parse-community/parse-server/issues/8391)) ([1c37a7c](https://github.com/parse-community/parse-server/commit/1c37a7cd0715949a70b220a629071c7dab7d5e7b)) +* Cloud Code trigger `beforeSave` does not work with `Parse.Role` ([#8320](https://github.com/parse-community/parse-server/issues/8320)) ([f29d972](https://github.com/parse-community/parse-server/commit/f29d9720e9b37918fd885c97a31e34c42750e724)) +* ES6 modules do not await the import of Cloud Code files ([#8368](https://github.com/parse-community/parse-server/issues/8368)) ([a7bd180](https://github.com/parse-community/parse-server/commit/a7bd180cddd784c8735622f22e012c342ad535fb)) +* Nested objects are encoded incorrectly for MongoDB ([#8209](https://github.com/parse-community/parse-server/issues/8209)) ([1412666](https://github.com/parse-community/parse-server/commit/1412666f75829612de6fb9d7ccae35761c9b75cb)) +* Parse Server option `masterKeyIps` does not include localhost by default for IPv6 ([#8322](https://github.com/parse-community/parse-server/issues/8322)) ([ab82635](https://github.com/parse-community/parse-server/commit/ab82635b0d4cf323a07ddee51fee587b43dce95c)) +* Rate limiter may reject requests that contain a session token ([#8399](https://github.com/parse-community/parse-server/issues/8399)) ([c114dc8](https://github.com/parse-community/parse-server/commit/c114dc8831055d74187b9dfb4c9eeb558520237c)) +* Remove Node 12 and Node 17 support ([#8279](https://github.com/parse-community/parse-server/issues/8279)) ([2546cc8](https://github.com/parse-community/parse-server/commit/2546cc8572bea6610cb9b3c7401d9afac0e3c1d6)) +* Schema without class level permissions may cause error ([#8409](https://github.com/parse-community/parse-server/issues/8409)) ([aa2cd51](https://github.com/parse-community/parse-server/commit/aa2cd51b703388d925e4572e5c2b2d883c68e49c)) +* The client IP address may be determined incorrectly in some cases; this fixes a security vulnerability in which the Parse Server option `masterKeyIps` may be circumvented, see [GHSA-vm5r-c87r-pf6x](https://github.com/parse-community/parse-server/security/advisories/GHSA-vm5r-c87r-pf6x) ([#8372](https://github.com/parse-community/parse-server/issues/8372)) ([892040d](https://github.com/parse-community/parse-server/commit/892040dc2f82a3e2abe2824e4b553521b6f894de)) +* Throwing error in Cloud Code Triggers `afterLogin`, `afterLogout` crashes server ([#8280](https://github.com/parse-community/parse-server/issues/8280)) ([130d290](https://github.com/parse-community/parse-server/commit/130d29074e3f763460e5685d0b9059e5a333caff)) + +### Features + +* Access the internal scope of Parse Server using the new `maintenanceKey`; the internal scope contains unofficial and undocumented fields (prefixed with underscore `_`) which are used internally by Parse Server; you may want to manipulate these fields for out-of-band changes such as data migration or correction tasks; changes within the internal scope of Parse Server may happen at any time without notice or changelog entry, it is therefore recommended to look at the source code of Parse Server to understand the effects of manipulating internal fields before using the key; it is discouraged to use the `maintenanceKey` for routine operations in a production environment; see [access scopes](https://github.com/parse-community/parse-server#access-scopes) ([#8212](https://github.com/parse-community/parse-server/issues/8212)) ([f3bcc93](https://github.com/parse-community/parse-server/commit/f3bcc9365cd6f08b0a32c132e8e5ff6d1b650863)) +* Adapt `verifyServerUrl` for new asynchronous Parse Server start-up states ([#8366](https://github.com/parse-community/parse-server/issues/8366)) ([ffa4974](https://github.com/parse-community/parse-server/commit/ffa4974158615fbff4a2692b9db41dcb50d3f77b)) +* Add `ParseQuery.watch` to trigger LiveQuery only on update of specific fields ([#8028](https://github.com/parse-community/parse-server/issues/8028)) ([fc92faa](https://github.com/parse-community/parse-server/commit/fc92faac75107b3392eeddd916c4c5b45e3c5e0c)) +* Add Node 19 support ([#8363](https://github.com/parse-community/parse-server/issues/8363)) ([a4990dc](https://github.com/parse-community/parse-server/commit/a4990dcd29abcb4442f3c424aff482a0a116160f)) +* Add option to change the log level of the logs emitted by triggers ([#8328](https://github.com/parse-community/parse-server/issues/8328)) ([8f3b694](https://github.com/parse-community/parse-server/commit/8f3b694e39d4a966567e50dbea4d62e954fa5c06)) +* Add request rate limiter based on IP address ([#8174](https://github.com/parse-community/parse-server/issues/8174)) ([6c79f6a](https://github.com/parse-community/parse-server/commit/6c79f6a69e25e47846e3b0685d6bdfd6b91086b1)) +* Asynchronous initialization of Parse Server ([#8232](https://github.com/parse-community/parse-server/issues/8232)) ([99fcf45](https://github.com/parse-community/parse-server/commit/99fcf45e55c368de2345b0c4d780e70e0adf0e15)) +* Improve authentication adapter interface to support multi-factor authentication (MFA), authentication challenges, and provide a more powerful interface for writing custom authentication adapters ([#8156](https://github.com/parse-community/parse-server/issues/8156)) ([5bbf9ca](https://github.com/parse-community/parse-server/commit/5bbf9cade9a527787fd1002072d4013ab5d8db2b)) +* Reduce Docker image size by improving stages ([#8359](https://github.com/parse-community/parse-server/issues/8359)) ([40810b4](https://github.com/parse-community/parse-server/commit/40810b48ebde8b1f21d2448a3a4de0585b1b5e34)) +* Remove deprecation `DEPPS1`: Native MongoDB syntax in aggregation pipeline ([#8362](https://github.com/parse-community/parse-server/issues/8362)) ([d0d30c4](https://github.com/parse-community/parse-server/commit/d0d30c4f1394f563724644a8fc81734be538a2c0)) +* Remove deprecation `DEPPS2`: Config option `directAccess` defaults to true ([#8284](https://github.com/parse-community/parse-server/issues/8284)) ([f535ee6](https://github.com/parse-community/parse-server/commit/f535ee6ec2abba63f702127258ca49fa5b4e08c9)) +* Remove deprecation `DEPPS3`: Config option `enforcePrivateUsers` defaults to `true` ([#8283](https://github.com/parse-community/parse-server/issues/8283)) ([ed499e3](https://github.com/parse-community/parse-server/commit/ed499e32a21bab9a874a9e5367dc71248ce836c4)) +* Remove deprecation `DEPPS4`: Remove convenience method for http request `Parse.Cloud.httpRequest` ([#8287](https://github.com/parse-community/parse-server/issues/8287)) ([2d79c08](https://github.com/parse-community/parse-server/commit/2d79c0835b6a9acaf20d5c943d9b4619bb96831c)) +* Remove support for MongoDB 4.0 ([#8292](https://github.com/parse-community/parse-server/issues/8292)) ([37245f6](https://github.com/parse-community/parse-server/commit/37245f62ce83516b6b95a54b850f0274ef680478)) +* Restrict use of `masterKey` to localhost by default ([#8281](https://github.com/parse-community/parse-server/issues/8281)) ([6c16021](https://github.com/parse-community/parse-server/commit/6c16021a1f03a70a6d9e68cb64df362d07f3b693)) +* Upgrade Node Package Manager lock file `package-lock.json` to version 2 ([#8285](https://github.com/parse-community/parse-server/issues/8285)) ([ee72467](https://github.com/parse-community/parse-server/commit/ee7246733d63e4bda20401f7b00262ff03299f20)) +* Upgrade Redis 3 to 4 ([#8293](https://github.com/parse-community/parse-server/issues/8293)) ([7d622f0](https://github.com/parse-community/parse-server/commit/7d622f06a4347e0ad2cba9a4ec07d8d4fb0f67bc)) +* Upgrade Redis 3 to 4 for LiveQuery ([#8333](https://github.com/parse-community/parse-server/issues/8333)) ([b2761fb](https://github.com/parse-community/parse-server/commit/b2761fb3786b519d9bbcf35be54309d2d35da1a9)) +* Upgrade to Parse JavaScript SDK 4 ([#8332](https://github.com/parse-community/parse-server/issues/8332)) ([9092874](https://github.com/parse-community/parse-server/commit/9092874a9a482a24dfdce1dce56615702999d6b8)) +* Write log entry when request with master key is rejected as outside of `masterKeyIps` ([#8350](https://github.com/parse-community/parse-server/issues/8350)) ([e22b73d](https://github.com/parse-community/parse-server/commit/e22b73d4b700c8ff745aa81726c6680082294b45)) + + +### BREAKING CHANGES + +* The Docker image does not contain the git dependency anymore; if you have been using git as a transitive dependency it now needs to be explicitly installed in your Docker file, for example with `RUN apk --no-cache add git` (#8359) ([40810b4](40810b4)) +* Fields in the internal scope of Parse Server (prefixed with underscore `_`) are only returned using the new `maintenanceKey`; previously the `masterKey` allowed reading of internal fields; see [access scopes](https://github.com/parse-community/parse-server#access-scopes) for a comparison of the keys' access permissions (#8212) ([f3bcc93](f3bcc93)) +* The method `ParseServer.verifyServerUrl` now returns a promise instead of a callback. ([ffa4974](ffa4974)) +* The MongoDB aggregation pipeline requires native MongoDB syntax instead of the custom Parse Server syntax; for example pipeline stage names require a leading dollar sign like `$match` and the MongoDB document ID is referenced using `_id` instead of `objectId` (#8362) ([d0d30c4](d0d30c4)) +* The mechanism to determine the client IP address has been rewritten; to correctly determine the IP address it is now required to set the Parse Server option `trustProxy` accordingly if Parse Server runs behind a proxy server, see the express framework's [trust proxy](https://expressjs.com/en/guide/behind-proxies.html) setting (#8372) ([892040d](892040d)) +* The Node Package Manager lock file `package-lock.json` is upgraded to version 2; while it is backwards with version 1 for the npm installer, consider this if you run any non-npm analysis tools that use the lock file (#8285) ([ee72467](ee72467)) +* This release introduces the asynchronous initialization of Parse Server to prevent mounting Parse Server before being ready to receive request; it changes how Parse Server is imported, initialized and started; it also removes the callback `serverStartComplete`; see the [Parse Server 6 migration guide](https://github.com/parse-community/parse-server/blob/alpha/6.0.0.md) for more details (#8232) ([99fcf45](99fcf45)) +* Nested objects are now properly stored in the database using JSON serialization; previously, due to a bug only top-level objects were serialized, but nested objects were saved as raw JSON; for example, a nested `Date` object was saved as a JSON object like `{ "__type": "Date", "iso": "2020-01-01T00:00:00.000Z" }` instead of its serialized representation `2020-01-01T00:00:00.000Z` (#8209) ([1412666](1412666)) +* The Parse Server option `enforcePrivateUsers` is set to `true` by default; in previous releases this option defaults to `false`; this change improves the default security configuration of Parse Server (#8283) ([ed499e3](ed499e3)) +* This release restricts the use of `masterKey` to localhost by default; if you are using Parse Dashboard on a different server to connect to Parse Server you need to add the IP address of the server that hosts Parse Dashboard to this option (#8281) ([6c16021](6c16021)) +* This release upgrades to Redis 4; if you are using the Redis cache adapter with Parse Server then this is a breaking change as the Redis client options have changed; see the [Redis migration guide](https://github.com/redis/node-redis/blob/redis%404.0.0/docs/v3-to-v4.md) for more details (#8293) ([7d622f0](7d622f0)) +* This release removes support for MongoDB 4.0; the new minimum supported MongoDB version is 4.2. which also removes support for the deprecated MongoDB MMAPv1 storage engine ([37245f6](37245f6)) +* Throwing an error in Cloud Code Triggers `afterLogin`, `afterLogout` returns a rejected promise; in previous releases it crashed the server if you did not handle the error on the Node.js process level; consider adapting your code if your app currently handles these errors on the Node.js process level with `process.on('unhandledRejection', ...)` ([130d290](130d290)) +* Config option `directAccess` defaults to true; set this to `false` in environments where multiple Parse Server instances run behind a load balancer and Parse requests within the current Node.js environment should be routed via the load balancer and distributed as HTTP requests among all instances via the `serverURL`. ([f535ee6](f535ee6)) +* The convenience method for HTTP requests `Parse.Cloud.httpRequest` is removed; use your preferred 3rd party library for making HTTP requests ([2d79c08](2d79c08)) +* This release removes Node 12 and Node 17 support ([2546cc8](2546cc8)) + # [5.4.0](https://github.com/parse-community/parse-server/compare/5.3.3...5.4.0) (2022-11-19) diff --git a/ci/definitionsCheck.js b/ci/definitionsCheck.js new file mode 100644 index 0000000000..e73473a984 --- /dev/null +++ b/ci/definitionsCheck.js @@ -0,0 +1,26 @@ +const fs = require('fs').promises; +const { exec } = require('child_process'); +const core = require('@actions/core'); +const util = require('util'); +(async () => { + const [currentDefinitions, currentDocs] = await Promise.all([ + fs.readFile('./src/Options/Definitions.js', 'utf8'), + fs.readFile('./src/Options/docs.js', 'utf8'), + ]); + const execute = util.promisify(exec); + await execute('npm run definitions'); + const [newDefinitions, newDocs] = await Promise.all([ + fs.readFile('./src/Options/Definitions.js', 'utf8'), + fs.readFile('./src/Options/docs.js', 'utf8'), + ]); + if (currentDefinitions !== newDefinitions || currentDocs !== newDocs) { + console.error( + '\x1b[31m%s\x1b[0m', + 'Definitions files cannot be updated manually. Please update src/Options/index.js then run `npm run definitions` to generate definitions.' + ); + core.error('Definitions files cannot be updated manually. Please update src/Options/index.js then run `npm run definitions` to generate definitions.'); + process.exit(1); + } else { + process.exit(0); + } +})(); diff --git a/jsdoc-conf.json b/jsdoc-conf.json index ad059acda1..efbaa0a37c 100644 --- a/jsdoc-conf.json +++ b/jsdoc-conf.json @@ -1,10 +1,16 @@ { "plugins": ["node_modules/jsdoc-babel", "plugins/markdown"], "babel": { - "plugins": ["@babel/plugin-transform-flow-strip-types"] + "plugins": ["@babel/plugin-transform-flow-strip-types"] }, "source": { - "include": ["./README.md", "./src/cloud-code", "./src/Options/docs.js", "./src/ParseServer.js", "./src/Adapters"], + "include": [ + "README.md", + "./src/cloud-code", + "./src/Options/docs.js", + "./src/ParseServer.js", + "./src/Adapters" + ], "excludePattern": "(^|\\/|\\\\)_" }, "templates": { @@ -17,7 +23,18 @@ "monospaceLinks": false }, "opts": { - "template": "node_modules/@parse/minami", - "recurse": true + "encoding": "utf8", + "readme": "./README.md", + "recurse": true, + "template": "./node_modules/clean-jsdoc-theme", + "theme_opts": { + "default_theme": "dark", + "title": "", + "create_style": "header, .sidebar-section-title, .sidebar-title { color: #139cee !important } .logo { margin-left : 40px; margin-right: 40px }" + } + }, + "markdown": { + "hardwrap": false, + "idInHeadings": true } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index ce3703a489..051475f8f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,19730 @@ { "name": "parse-server", - "version": "5.4.0", - "lockfileVersion": 1, + "version": "7.0.0", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "parse-server", + "version": "7.0.0", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@apollo/server": "4.10.1", + "@babel/eslint-parser": "7.21.8", + "@graphql-tools/merge": "8.4.1", + "@graphql-tools/schema": "10.0.3", + "@graphql-tools/utils": "8.12.0", + "@parse/fs-files-adapter": "2.0.1", + "@parse/push-adapter": "5.1.1", + "bcryptjs": "2.4.3", + "body-parser": "1.20.2", + "commander": "12.0.0", + "cors": "2.8.5", + "deepcopy": "2.1.0", + "express": "4.18.2", + "express-rate-limit": "6.11.2", + "follow-redirects": "1.15.6", + "graphql": "16.8.1", + "graphql-list-fields": "2.0.4", + "graphql-relay": "0.10.0", + "graphql-tag": "2.12.6", + "graphql-upload": "15.0.2", + "intersect": "1.0.1", + "jsonwebtoken": "9.0.0", + "jwks-rsa": "3.1.0", + "ldapjs": "3.0.7", + "lodash": "4.17.21", + "lru-cache": "10.1.0", + "mime": "3.0.0", + "mongodb": "5.9.0", + "mustache": "4.2.0", + "otpauth": "9.2.2", + "parse": "5.0.0", + "path-to-regexp": "6.2.1", + "pg-monitor": "2.0.0", + "pg-promise": "11.5.4", + "pluralize": "8.0.0", + "rate-limit-redis": "3.0.2", + "redis": "4.6.13", + "semver": "7.6.0", + "subscriptions-transport-ws": "0.11.0", + "tv4": "1.3.0", + "uuid": "9.0.1", + "winston": "3.12.0", + "winston-daily-rotate-file": "5.0.0", + "ws": "8.16.0" + }, + "bin": { + "parse-server": "bin/parse-server" + }, + "devDependencies": { + "@actions/core": "1.9.1", + "@apollo/client": "3.9.5", + "@babel/cli": "7.23.9", + "@babel/core": "7.24.0", + "@babel/plugin-proposal-object-rest-spread": "7.10.0", + "@babel/plugin-transform-flow-strip-types": "7.23.3", + "@babel/preset-env": "7.24.0", + "@saithodev/semantic-release-backmerge": "2.1.2", + "@semantic-release/changelog": "5.0.1", + "@semantic-release/commit-analyzer": "8.0.1", + "@semantic-release/git": "9.0.0", + "@semantic-release/github": "7.2.3", + "@semantic-release/npm": "7.1.3", + "@semantic-release/release-notes-generator": "9.0.3", + "all-node-versions": "11.3.0", + "apollo-upload-client": "17.0.0", + "clean-jsdoc-theme": "4.2.7", + "cross-env": "7.0.2", + "deep-diff": "1.0.2", + "eslint": "8.26.0", + "eslint-plugin-flowtype": "8.0.3", + "flow-bin": "0.119.1", + "form-data": "4.0.0", + "graphql-tag": "2.12.6", + "husky": "9.0.11", + "jasmine": "3.5.0", + "jasmine-spec-reporter": "7.0.0", + "jsdoc": "4.0.2", + "jsdoc-babel": "0.5.0", + "lint-staged": "10.2.3", + "madge": "6.1.0", + "mock-files-adapter": "file:spec/dependencies/mock-files-adapter", + "mock-mail-adapter": "file:spec/dependencies/mock-mail-adapter", + "mongodb-runner": "5.4.4", + "mongodb-version-list": "1.0.0", + "node-abort-controller": "3.0.1", + "node-fetch": "3.2.10", + "nyc": "15.1.0", + "prettier": "2.0.5", + "semantic-release": "17.4.6", + "yaml": "1.10.0" + }, + "engines": { + "node": ">=18.0.0 <21" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parse-server" + }, + "optionalDependencies": { + "@node-rs/bcrypt": "1.1.0" + } + }, + "node_modules/@actions/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", + "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", + "dev": true, + "dependencies": { + "@actions/http-client": "^2.0.1", + "uuid": "^8.3.2" + } + }, + "node_modules/@actions/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==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@actions/http-client": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz", + "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==", + "dev": true, + "dependencies": { + "tunnel": "^0.0.6" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@apollo/cache-control-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@apollo/cache-control-types/-/cache-control-types-1.0.3.tgz", + "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==", + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/client": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.9.5.tgz", + "integrity": "sha512-7y+c8MTPU+hhTwvcGVtMMGIgWduzrvG1mz5yJMRyqYbheBkkky3Lki6ADWVSBXG1lZoOtPYvB2zDgVfKb2HSsw==", + "dev": true, + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@wry/caches": "^1.0.0", + "@wry/equality": "^0.5.6", + "@wry/trie": "^0.5.0", + "graphql-tag": "^2.12.6", + "hoist-non-react-statics": "^3.3.2", + "optimism": "^0.18.0", + "prop-types": "^15.7.2", + "rehackt": "0.0.5", + "response-iterator": "^0.2.6", + "symbol-observable": "^4.0.0", + "ts-invariant": "^0.10.3", + "tslib": "^2.3.0", + "zen-observable-ts": "^1.2.5" + }, + "peerDependencies": { + "graphql": "^15.0.0 || ^16.0.0", + "graphql-ws": "^5.5.5", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" + }, + "peerDependenciesMeta": { + "graphql-ws": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "subscriptions-transport-ws": { + "optional": true + } + } + }, + "node_modules/@apollo/protobufjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", + "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", + "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", + "long": "^4.0.0" + }, + "bin": { + "apollo-pbjs": "bin/pbjs", + "apollo-pbts": "bin/pbts" + } + }, + "node_modules/@apollo/server": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.10.1.tgz", + "integrity": "sha512-XGMOgTyzV4EBHQq0xQVKFry9hZF7AA/6nxxGLamqdxodhdSdGbU9jrlb5/XDveeGuXP3+5JDdrB2HcziVLJcMA==", + "dependencies": { + "@apollo/cache-control-types": "^1.0.3", + "@apollo/server-gateway-interface": "^1.1.1", + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.createhash": "^2.0.0", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.isnodelike": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0", + "@apollo/utils.usagereporting": "^2.1.0", + "@apollo/utils.withrequired": "^2.0.0", + "@graphql-tools/schema": "^9.0.0", + "@josephg/resolvable": "^1.0.0", + "@types/express": "^4.17.13", + "@types/express-serve-static-core": "^4.17.30", + "@types/node-fetch": "^2.6.1", + "async-retry": "^1.2.1", + "cors": "^2.8.5", + "express": "^4.17.1", + "loglevel": "^1.6.8", + "lru-cache": "^7.10.1", + "negotiator": "^0.6.3", + "node-abort-controller": "^3.1.1", + "node-fetch": "^2.6.7", + "uuid": "^9.0.0", + "whatwg-mimetype": "^3.0.0" + }, + "engines": { + "node": ">=14.16.0" + }, + "peerDependencies": { + "graphql": "^16.6.0" + } + }, + "node_modules/@apollo/server-gateway-interface": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@apollo/server-gateway-interface/-/server-gateway-interface-1.1.1.tgz", + "integrity": "sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==", + "dependencies": { + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/server/node_modules/@graphql-tools/schema": { + "version": "9.0.19", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.19.tgz", + "integrity": "sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==", + "dependencies": { + "@graphql-tools/merge": "^8.4.1", + "@graphql-tools/utils": "^9.2.1", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@apollo/server/node_modules/@graphql-tools/utils": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@apollo/server/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@apollo/server/node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + }, + "node_modules/@apollo/server/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@apollo/server/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/@apollo/server/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/@apollo/server/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/@apollo/usage-reporting-protobuf": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.1.tgz", + "integrity": "sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==", + "dependencies": { + "@apollo/protobufjs": "1.2.7" + } + }, + "node_modules/@apollo/utils.createhash": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.createhash/-/utils.createhash-2.0.1.tgz", + "integrity": "sha512-fQO4/ZOP8LcXWvMNhKiee+2KuKyqIcfHrICA+M4lj/h/Lh1H10ICcUtk6N/chnEo5HXu0yejg64wshdaiFitJg==", + "dependencies": { + "@apollo/utils.isnodelike": "^2.0.1", + "sha.js": "^2.4.11" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.dropunuseddefinitions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-2.0.1.tgz", + "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.fetcher": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.fetcher/-/utils.fetcher-2.0.1.tgz", + "integrity": "sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.isnodelike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.isnodelike/-/utils.isnodelike-2.0.1.tgz", + "integrity": "sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.keyvaluecache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-2.1.1.tgz", + "integrity": "sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==", + "dependencies": { + "@apollo/utils.logger": "^2.0.1", + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.keyvaluecache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@apollo/utils.logger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-2.0.1.tgz", + "integrity": "sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@apollo/utils.printwithreducedwhitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-2.0.1.tgz", + "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.removealiases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-2.0.1.tgz", + "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.sortast": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-2.0.1.tgz", + "integrity": "sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==", + "dependencies": { + "lodash.sortby": "^4.7.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.stripsensitiveliterals": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-2.0.1.tgz", + "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.usagereporting": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-2.1.0.tgz", + "integrity": "sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==", + "dependencies": { + "@apollo/usage-reporting-protobuf": "^4.1.0", + "@apollo/utils.dropunuseddefinitions": "^2.0.1", + "@apollo/utils.printwithreducedwhitespace": "^2.0.1", + "@apollo/utils.removealiases": "2.0.1", + "@apollo/utils.sortast": "^2.0.1", + "@apollo/utils.stripsensitiveliterals": "^2.0.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "graphql": "14.x || 15.x || 16.x" + } + }, + "node_modules/@apollo/utils.withrequired": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.withrequired/-/utils.withrequired-2.0.1.tgz", + "integrity": "sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@babel/cli": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.9.tgz", + "integrity": "sha512-vB1UXmGDNEhcf1jNAHKT9IlYk1R+hehVTLFlCLHBi8gfuHQGP6uRjgXVYU0EVlI/qwAWpstqkBdf2aez3/z/5Q==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "commander": "^4.0.1", + "convert-source-map": "^2.0.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/cli/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@babel/cli/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", + "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/@babel/eslint-parser/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/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/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==", + "dependencies": { + "@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/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", + "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.0.tgz", + "integrity": "sha512-DOD+4TqMcRKJdAfN08+v9cciK5d0HW5hwTndOoKZEfEzU/mRrKboheD5mnWU4Q96VOnDdAj86kKjZhoQyG6s+A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.9.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", + "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", + "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz", + "integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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, + "peer": 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-react-jsx/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, + "peer": 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-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", + "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@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-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.8", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.24.0", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.21.0.tgz", + "integrity": "sha512-TDD4UJzos3JJtM+tHX+w2Uc+KWj7GV+VKKFdMVd2Rx8sdA19hcc3P3AHFYd5LVOw+pYuSd5lICC3gm52B6Rwxw==", + "dependencies": { + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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/@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/@dependents/detective-less": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-3.0.2.tgz", + "integrity": "sha512-1YUvQ+e0eeTWAHoN8Uz2x2U37jZs6IGutiIE5LXId7cxfUGhtZjzxE06FdUiuiRrW+UE0vNCdSNPH2lY4dQCOQ==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^5.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.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" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@fastify/busboy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz", + "integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==", + "dependencies": { + "text-decoding": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", + "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" + }, + "node_modules/@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" + }, + "node_modules/@firebase/component": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", + "integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==", + "dependencies": { + "@firebase/util": "1.9.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.3.tgz", + "integrity": "sha512-9fjqLt9JzL46gw9+NRqsgQEMjgRwfd8XtzcKqG+UYyhVeFCdVRQ0Wp6Dw/dvYHnbH5vNEKzNv36dcB4p+PIAAA==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.0", + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.5", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.4", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.3.tgz", + "integrity": "sha512-7tHEOcMbK5jJzHWyphPux4osogH/adWwncxdMxdBpB9g1DNIyY4dcz1oJdlkXGM/i/AjUBesZsd5CuwTRTBNTw==", + "dependencies": { + "@firebase/component": "0.6.5", + "@firebase/database": "1.0.3", + "@firebase/database-types": "1.0.1", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.1.tgz", + "integrity": "sha512-Tmcmx5XgiI7UVF/4oGg2P3AOTfq3WKEPsm2yf+uXtN7uG/a4WTWhVMrXGYRY2ZUL1xPxv9V33wQRJ+CcrUhVXw==", + "dependencies": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.4" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/util": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", + "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@google-cloud/firestore": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.3.1.tgz", + "integrity": "sha512-YluLZbJK3dHXq6Ns5URCtr6hjBiG+6EM17QSivjaozPYDsv1R9a9mkWPz+jCQrb6Ewz6mxp3zavu6DXxvmSWLA==", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.0.4", + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz", + "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.7.0.tgz", + "integrity": "sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "compressible": "^2.0.12", + "duplexify": "^4.0.0", + "ent": "^2.2.0", + "fast-xml-parser": "^4.3.0", + "gaxios": "^6.0.2", + "google-auth-library": "^9.0.0", + "mime": "^3.0.0", + "mime-types": "^2.0.8", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/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==", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@graphql-tools/merge": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.1.tgz", + "integrity": "sha512-hssnPpZ818mxgl5+GfyOOSnnflAxiaTn1A1AojZcIbh4J52sS1Q0gSuBR5VrnUDjuxiqoCotpXdAQl+K+U6KLQ==", + "dependencies": { + "@graphql-tools/utils": "^9.2.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.3.tgz", + "integrity": "sha512-p28Oh9EcOna6i0yLaCFOnkcBDQECVf3SCexT6ktb86QNj9idnkhI+tCxnwZDh58Qvjd2nURdkbevvoZkvxzCog==", + "dependencies": { + "@graphql-tools/merge": "^9.0.3", + "@graphql-tools/utils": "^10.0.13", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/merge": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.3.tgz", + "integrity": "sha512-FeKv9lKLMwqDu0pQjPpF59GY3HReUkWXKsMIuMuJQOKh9BETu7zPEFUELvcw8w+lwZkl4ileJsHXC9+AnsT2Lw==", + "dependencies": { + "@graphql-tools/utils": "^10.0.13", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.0.tgz", + "integrity": "sha512-wLPqhgeZ9BZJPRoaQbsDN/CtJDPd/L4qmmtPkjI3NuYJ39x+Eqz1Sh34EAGMuDh+xlOHqBwHczkZUpoK9tvzjw==", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "cross-inspect": "1.0.0", + "dset": "^3.1.2", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "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==", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "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==", + "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/@grpc/grpc-js": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.1.tgz", + "integrity": "sha512-55ONqFytZExfOIjF1RjXPcVmT/jJqFzbbDqxK9jmRV4nxiYWtL9hENSW1Jfx0SdZfrvoqd44YJ/GJTqfRrawSQ==", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "optional": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader/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==", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@grpc/proto-loader/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==", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader/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==", + "optional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@grpc/proto-loader/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==", + "optional": true + }, + "node_modules/@grpc/proto-loader/node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true + }, + "node_modules/@grpc/proto-loader/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@grpc/proto-loader/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "optional": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader/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==", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "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==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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==" + }, + "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==", + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "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==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "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==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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": ">=8" + } + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "engines": { + "node": ">=6.0.0" + } + }, + "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==" + }, + "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==", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jsdoc/salty": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.5.tgz", + "integrity": "sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, + "node_modules/@ldapjs/asn1": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-2.0.0.tgz", + "integrity": "sha512-G9+DkEOirNgdPmD0I8nu57ygQJKOOgFEMKknEuQvIHbGLwP3ny1mY+OTUYLCbCaGJP4sox5eYgBJRuSUpnAddA==" + }, + "node_modules/@ldapjs/attribute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/attribute/-/attribute-1.0.0.tgz", + "integrity": "sha512-ptMl2d/5xJ0q+RgmnqOi3Zgwk/TMJYG7dYMC0Keko+yZU6n+oFM59MjQOUht5pxJeS4FWrImhu/LebX24vJNRQ==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/change": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/change/-/change-1.0.0.tgz", + "integrity": "sha512-EOQNFH1RIku3M1s0OAJOzGfAohuFYXFY4s73wOhRm4KFGhmQQ7MChOh2YtYu9Kwgvuq1B0xKciXVzHCGkB5V+Q==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0" + } + }, + "node_modules/@ldapjs/controls": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/controls/-/controls-2.1.0.tgz", + "integrity": "sha512-2pFdD1yRC9V9hXfAWvCCO2RRWK9OdIEcJIos/9cCVP9O4k72BY1bLDQQ4KpUoJnl4y/JoD4iFgM+YWT3IfITWw==", + "dependencies": { + "@ldapjs/asn1": "^1.2.0", + "@ldapjs/protocol": "^1.2.1" + } + }, + "node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-1.2.0.tgz", + "integrity": "sha512-KX/qQJ2xxzvO2/WOvr1UdQ+8P5dVvuOLk/C9b1bIkXxZss8BaR28njXdPgFCpj5aHaf1t8PmuVnea+N9YG9YMw==" + }, + "node_modules/@ldapjs/dn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/dn/-/dn-1.1.0.tgz", + "integrity": "sha512-R72zH5ZeBj/Fujf/yBu78YzpJjJXG46YHFo5E4W1EqfNpo1UsVPqdLrRMXeKIsJT3x9dJVIfR6OpzgINlKpi0A==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/filter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ldapjs/filter/-/filter-2.1.1.tgz", + "integrity": "sha512-TwPK5eEgNdUO1ABPBUQabcZ+h9heDORE4V9WNZqCtYLKc06+6+UAJ3IAbr0L0bYTnkkWC/JEQD2F+zAFsuikNw==", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/messages": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ldapjs/messages/-/messages-1.3.0.tgz", + "integrity": "sha512-K7xZpXJ21bj92jS35wtRbdcNrwmxAtPwy4myeh9duy/eR3xQKvikVycbdWVzkYEAVE5Ce520VXNOwCHjomjCZw==", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.2.0" + } + }, + "node_modules/@ldapjs/protocol": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ldapjs/protocol/-/protocol-1.2.1.tgz", + "integrity": "sha512-O89xFDLW2gBoZWNXuXpBSM32/KealKCTb3JGtJdtUQc7RjAk8XzrRgyz02cPAwGKwKPxy0ivuC7UP9bmN87egQ==" + }, + "node_modules/@mongodb-js/mongodb-downloader": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-downloader/-/mongodb-downloader-0.2.8.tgz", + "integrity": "sha512-y+mgw9QspvgTLRNHZJRS+DUTPk45RWpvYD1MaGDWhZ4ajffvxGqanY+Z4R6z01n+tIRmQvpShzF6zk+2Pr9d6w==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "decompress": "^4.2.1", + "mongodb-download-url": "^1.3.0", + "node-fetch": "^2.6.11", + "tar": "^6.1.15" + } + }, + "node_modules/@mongodb-js/mongodb-downloader/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@mongodb-js/mongodb-downloader/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/@mongodb-js/mongodb-downloader/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/@mongodb-js/mongodb-downloader/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz", + "integrity": "sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@napi-rs/triples": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/triples/-/triples-1.1.0.tgz", + "integrity": "sha512-XQr74QaLeMiqhStEhLn1im9EOMnkypp7MZOwQhGzqp2Weu5eQJbpPxWxixxlYRKWPOmJjsk6qYfYH9kq43yc2w==", + "optional": true + }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "optional": true + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@node-rs/bcrypt": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.1.0.tgz", + "integrity": "sha512-5vjztYYcPCyvamO3C+hrNaVplZC9yEMzGxJECliQR5hkUOQdrtulCpigNOr1POWpC1YsJH0ZL+ktWop+cl5Qqw==", + "optional": true, + "dependencies": { + "@node-rs/helper": "^1.1.0" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/bcrypt-android-arm64": "^1.1.0", + "@node-rs/bcrypt-darwin-arm64": "^1.1.0", + "@node-rs/bcrypt-darwin-x64": "^1.1.0", + "@node-rs/bcrypt-linux-arm-gnueabihf": "^1.1.0", + "@node-rs/bcrypt-linux-arm64-gnu": "^1.1.0", + "@node-rs/bcrypt-linux-x64-gnu": "^1.1.0", + "@node-rs/bcrypt-linux-x64-musl": "^1.1.0", + "@node-rs/bcrypt-win32-ia32-msvc": "^1.1.0", + "@node-rs/bcrypt-win32-x64-msvc": "^1.1.0" + } + }, + "node_modules/@node-rs/bcrypt-android-arm64": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.6.1.tgz", + "integrity": "sha512-KGpWqSKKIKoKrW1QnzY7ihZREMiPXrMO7ps+3vtLdyiRBqigj10TB/zjolbomZAkb/53jhFkIJpYQkbK5hqh0Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-darwin-arm64": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.6.1.tgz", + "integrity": "sha512-iUfuCYzqJTvi36ZEcEOgphb0C+4qI5aP+nIKsg/YEnerhbCKNRxhQXoxW1bayohpqjlenZ4jOKZXi1h2stMgPQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-darwin-x64": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.6.1.tgz", + "integrity": "sha512-AQjjVgv5Z2jw8Krv8zbqxSgse6zBIYAnjVBHd74oEPDvdZcXomNc7Pv8eOletPAHRYaGcA2lrCBNEp5Un7ddsA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm-gnueabihf": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.6.1.tgz", + "integrity": "sha512-Hpy0pEXrxmIe0IYdWaH4vIka6xk2s4TdrnmQaPR7wSMfBQlGpyBXmgfCtPmGER/pb5Ft9H6q2l3Sh0w24X0PLQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm64-gnu": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.6.1.tgz", + "integrity": "sha512-R6ziaQw0pgMMzLVVD7Q76Iq01HGuwSNnbUgTgrqTbmw031dTlh7rnlJd1jXM6gBjR6kPTuV98hqMhMyHjrLKIg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-x64-gnu": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.6.1.tgz", + "integrity": "sha512-GwOFrzHN+Em+OhViA9hCmr/VGTVVl9OcASgG6ehT1PM7CB6zuhONBuvCUCoRyP03zY5ZkHbv8ODqAj9a9WGV2A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-x64-musl": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.6.1.tgz", + "integrity": "sha512-koksZzVpwwmLsJTzUa0RfDgFNzSaXsUUo4wDpgQsn9MON0epSxrkZAc3Lw2oGrDRIhgH/kv/9aZExJEFo1Mj9A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-win32-ia32-msvc": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.6.1.tgz", + "integrity": "sha512-rp2kChdJf0dqYoynZzY8MjcSWrdZ3/B3EszZMlEjDfj40EXF7TOYNIavk58qPm4m70II1l46bi51FStEjvA3bw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-win32-x64-msvc": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.6.1.tgz", + "integrity": "sha512-6ykZKa9ydU9CFx2hbR1wuzpngx63MPK7mJMZgbetyOPpGEyixHDz/mSvpywptCGUEuuDbOE4rbc3Afw6dEf4TA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/helper": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-1.3.3.tgz", + "integrity": "sha512-p4OdfQObGN9YFy5WZaGwlPYICQSe7xZYyXB0sxREmvj1HzGKp5bPg2PlfgfMZEfnjIA882B9ZrnagYzZihIwjA==", + "optional": true, + "dependencies": { + "@napi-rs/triples": "^1.1.0" + } + }, + "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==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "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==", + "engines": { + "node": ">= 8" + } + }, + "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==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dev": true, + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", + "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.40.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", + "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.39.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/request/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@octokit/request/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/@octokit/request/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/@octokit/request/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dev": true, + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "node_modules/@parse/fs-files-adapter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@parse/fs-files-adapter/-/fs-files-adapter-2.0.1.tgz", + "integrity": "sha512-9DY0T9lK73Ysw+wxxsBt9rpxWxJpMlHl/fTW175XSajusW0ZP5jERI3BTKeclV28eVmSU690EO2vnwCURsPZ7g==" + }, + "node_modules/@parse/node-apn": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@parse/node-apn/-/node-apn-6.0.1.tgz", + "integrity": "sha512-QQxqEN/zbtEkSgj41oX/tQUavML+G+JHeQi2YVlgZlponnwIxA3fb5tEbXPm+fdR6rL1pi2/z2PcOwINOyx2eA==", + "dependencies": { + "debug": "4.3.3", + "jsonwebtoken": "9.0.0", + "node-forge": "1.3.1", + "verror": "1.10.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@parse/node-apn/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/@parse/node-gcm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@parse/node-gcm/-/node-gcm-1.0.2.tgz", + "integrity": "sha512-5LwLAYaGPWvuAyqaRr+4LD3Lq4V/A8DiznCFC2as9XBqfmhP7bwQMKKcymVcINrJGxPhNi69RrQpuEhIehtIqQ==", + "dependencies": { + "debug": "^3.1.0", + "lodash": "^4.17.10", + "request": "2.88.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@parse/node-gcm/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@parse/push-adapter": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@parse/push-adapter/-/push-adapter-5.1.1.tgz", + "integrity": "sha512-gazpr/H8tnEhQtDPPYctsvNU0ICkkZAB0wIOnt5AOFANZ9rldl9vRX/BONtmrpewNinfCnqkGUvI9+tVO+rw4w==", + "dependencies": { + "@parse/node-apn": "6.0.1", + "@parse/node-gcm": "1.0.2", + "firebase-admin": "12.0.0", + "npmlog": "7.0.1", + "parse": "4.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@parse/push-adapter/node_modules/parse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/parse/-/parse-4.2.0.tgz", + "integrity": "sha512-K8bWs0wM2qRhkSr6N16j8OvsF6Uallrynqng9e+tzR3RdKuB09vaJh48qrf9MbiJ1Ya4JZI7AfEHYF+ywEKs7Q==", + "dependencies": { + "@babel/runtime-corejs3": "7.21.0", + "idb-keyval": "6.2.0", + "react-native-crypto-js": "1.0.0", + "uuid": "9.0.0", + "ws": "8.13.0", + "xmlhttprequest": "1.8.0" + }, + "engines": { + "node": ">=14.21.0 <17 || >=18 <20" + }, + "optionalDependencies": { + "crypto-js": "4.1.1" + } + }, + "node_modules/@parse/push-adapter/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/@parse/push-adapter/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": 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": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "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/@redis/bloom": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/client": { + "version": "1.5.14", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz", + "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==", + "dependencies": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", + "yallist": "4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@redis/graph": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/json": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/search": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/time-series": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@saithodev/semantic-release-backmerge": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-backmerge/-/semantic-release-backmerge-2.1.2.tgz", + "integrity": "sha512-fNd8cmijjFIMp4GcdTAcug/7tr4k+8bAyvSsbLOnfyKCWyq42lg14vFZOryLiyLUAe8gpPlI7XzDPWyFTR5zug==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^2.2.0 || ^3.0.0", + "aggregate-error": "^3.1.0", + "debug": "^4.3.2", + "execa": "^5.1.1", + "lodash": "^4.17.21", + "semantic-release": ">=13.0.0" + } + }, + "node_modules/@samverschueren/stream-to-observable": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz", + "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==", + "dev": true, + "dependencies": { + "any-observable": "^0.3.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependenciesMeta": { + "rxjs": { + "optional": true + }, + "zen-observable": { + "optional": true + } + } + }, + "node_modules/@semantic-release/changelog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-5.0.1.tgz", + "integrity": "sha512-unvqHo5jk4dvAf2nZ3aw4imrlwQ2I50eVVvq9D47Qc3R+keNqepx1vDYwkjF8guFXnOYaYcR28yrZWno1hFbiw==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^9.0.0", + "lodash": "^4.17.4" + }, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "semantic-release": ">=15.8.0 <18.0.0" + } + }, + "node_modules/@semantic-release/changelog/node_modules/@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "node_modules/@semantic-release/commit-analyzer": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz", + "integrity": "sha512-5bJma/oB7B4MtwUkZC2Bf7O1MHfi4gWe4mA+MIQ3lsEV0b422Bvl1z5HRpplDnMLHH3EXMoRdEng6Ds5wUqA3A==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.7", + "debug": "^4.0.0", + "import-from": "^3.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "semantic-release": ">=16.0.0 <18.0.0" + } + }, + "node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@semantic-release/git": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-9.0.0.tgz", + "integrity": "sha512-AZ4Zha5NAPAciIJH3ipzw/WU9qLAn8ENaoVAhD6srRPxTpTzuV3NhNh14rcAo8Paj9dO+5u4rTKcpetOBluYVw==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^4.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "semantic-release": ">=16.0.0 <18.0.0" + } + }, + "node_modules/@semantic-release/git/node_modules/@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "node_modules/@semantic-release/git/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@semantic-release/git/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, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/git/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/@semantic-release/github": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-7.2.3.tgz", + "integrity": "sha512-lWjIVDLal+EQBzy697ayUNN8MoBpp+jYIyW2luOdqn5XBH4d9bQGfTnjuLyzARZBHejqh932HVjiH/j4+R7VHw==", + "dev": true, + "dependencies": { + "@octokit/rest": "^18.0.0", + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "bottleneck": "^2.18.1", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "fs-extra": "^10.0.0", + "globby": "^11.0.0", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "issue-parser": "^6.0.0", + "lodash": "^4.17.4", + "mime": "^2.4.3", + "p-filter": "^2.0.0", + "p-retry": "^4.0.0", + "url-join": "^4.0.0" + }, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "semantic-release": ">=16.0.0 <18.0.0" + } + }, + "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "node_modules/@semantic-release/github/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@semantic-release/github/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@semantic-release/npm": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-7.1.3.tgz", + "integrity": "sha512-x52kQ/jR09WjuWdaTEHgQCvZYMOTx68WnS+TZ4fya5ZAJw4oRtJETtrvUw10FdfM28d/keInQdc66R1Gw5+OEQ==", + "dev": true, + "dependencies": { + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "execa": "^5.0.0", + "fs-extra": "^10.0.0", + "lodash": "^4.17.15", + "nerf-dart": "^1.0.0", + "normalize-url": "^6.0.0", + "npm": "^7.0.0", + "rc": "^1.2.8", + "read-pkg": "^5.0.0", + "registry-auth-token": "^4.0.0", + "semver": "^7.1.2", + "tempy": "^1.0.0" + }, + "engines": { + "node": ">=10.19" + }, + "peerDependencies": { + "semantic-release": ">=16.0.0 <18.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "node_modules/@semantic-release/npm/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@semantic-release/release-notes-generator": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-9.0.3.tgz", + "integrity": "sha512-hMZyddr0u99OvM2SxVOIelHzly+PP3sYtJ8XOLHdMp8mrluN5/lpeTnIO27oeCYdupY/ndoGfvrqDjHqkSyhVg==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.0", + "conventional-changelog-writer": "^4.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.0", + "debug": "^4.0.0", + "get-stream": "^6.0.0", + "import-from": "^3.0.0", + "into-stream": "^6.0.0", + "lodash": "^4.17.4", + "read-pkg-up": "^7.0.0" + }, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "semantic-release": ">=15.8.0 <18.0.0" + } + }, + "node_modules/@sindresorhus/is": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/busboy": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.3.tgz", + "integrity": "sha512-YMBLFN/xBD8bnqywIlGyYqsNFXu6bsiY7h3Ae0kO17qEuTjsqeyYMRPSUDacIKIquws2Y6KjmxAyNx8xB3xQbw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "optional": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "dev": true + }, + "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/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "dependencies": { + "@types/node": "*", + "form-data": "4.0.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@types/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==" + }, + "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/@types/qs": { + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "optional": true, + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "optional": true + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.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/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@wry/caches": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz", + "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==", + "dev": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/context": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz", + "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==", + "dev": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/equality": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz", + "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==", + "dev": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/trie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz", + "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==", + "dev": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" + }, + "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": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "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==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.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==", + "devOptional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "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": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/all-node-versions": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-11.3.0.tgz", + "integrity": "sha512-psMkc5s3qpr+QMfires9bC4azRYciPWql1wqZKMsYRh1731qefQDH2X4+O19xSBX6u0Ra/8Y5diG6y/fEmqKsw==", + "dev": true, + "dependencies": { + "fetch-node-website": "^7.3.0", + "filter-obj": "^5.1.0", + "get-stream": "^6.0.0", + "global-cache-dir": "^4.3.1", + "is-plain-obj": "^4.1.0", + "path-exists": "^5.0.0", + "semver": "^7.3.7", + "write-file-atomic": "^4.0.1" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/all-node-versions/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/all-node-versions/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/all-node-versions/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", + "dev": true + }, + "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==", + "dev": true, + "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" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "optional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apollo-upload-client": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-17.0.0.tgz", + "integrity": "sha512-pue33bWVbdlXAGFPkgz53TTmxVMrKeQr0mdRcftNY+PoHIdbGZD0hoaXHvO6OePJAkFz7OiCFUf98p1G/9+Ykw==", + "dev": true, + "dependencies": { + "extract-files": "^11.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >= 16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/jaydenseric" + }, + "peerDependencies": { + "@apollo/client": "^3.0.0", + "graphql": "14 - 16" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "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==" + }, + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "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-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "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/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.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==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-options": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.1.tgz", + "integrity": "sha512-5lNGRB5g5i2bGIzb+J1QQE1iKU/WEMVBReFIc5pPDWjcPj23otPL0eI6PB2v7QPi0qU6Mhym5D3y0ZiSIOf3GA==", + "engines": { + "node": ">=10.0.0" + } + }, + "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_modules/ast-module-types": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-4.0.0.tgz", + "integrity": "sha512-Kd0o8r6CDazJGCRzs8Ivpn0xj19oNKrULhoJFzhGjRsLpekF2zyZs9Ukz+JvZhWD6smszfepakTFhAaYpsI12g==", + "dev": true, + "engines": { + "node": ">=12.0" + } + }, + "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/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "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/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "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/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", + "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.5.0", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "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/backoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "devOptional": true, + "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/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/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/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "optional": true, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "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", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "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": { + "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/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": 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": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bson": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz", + "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==", + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "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/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "dev": true + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.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/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.7", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.7.tgz", + "integrity": "sha512-I4SA6mKgDxcxVbSt/UmIkb9Ny8qSkg6ReBHtAAXnZHk7KOSx5g3DTiAOaYzcHCs6oOdHn+bip9T48E6tMvK9hw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.2", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caching-transform/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/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": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "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==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "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, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001594", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz", + "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "dev": true, + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "optional": true, + "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-jsdoc-theme": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/clean-jsdoc-theme/-/clean-jsdoc-theme-4.2.7.tgz", + "integrity": "sha512-yLLxwTFw7N9/toUCcFmKkwJmv4LO2pQWYNETcU3Vv+n2al2L2ohb7xWoXLjp5m3OljC9b1m+o4adzY0YH6Ep4A==", + "dev": true, + "dependencies": { + "@jsdoc/salty": "^0.2.4", + "fs-extra": "^10.1.0", + "html-minifier": "^4.0.0", + "klaw-sync": "^6.0.0", + "lodash": "^4.17.21", + "nanoid": "^3.3.4", + "showdown": "^2.1.0" + }, + "peerDependencies": { + "jsdoc": ">=3.x <=4.x" + } + }, + "node_modules/clean-jsdoc-theme/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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_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": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-progress": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.11.2.tgz", + "integrity": "sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==", + "dev": true, + "dependencies": { + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=4" + } + }, + "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": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "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": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "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/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "engines": { + "node": ">=0.10.0" + } + }, + "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/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/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/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/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/colors-option": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/colors-option/-/colors-option-4.5.0.tgz", + "integrity": "sha512-Soe5lerRg3erMRgYC0EC696/8dMCGpBzcQchFfi55Yrkja8F+P7cUt0LVTIg7u5ob5BexLZ/F1kO+ejmv+nq8w==", + "dev": true, + "dependencies": { + "chalk": "^5.0.1", + "is-plain-obj": "^4.1.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/colors-option/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/colors-option/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "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": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz", + "integrity": "sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer/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/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/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/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-js-compat": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "dev": true, + "dependencies": { + "browserslist": "^4.22.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.0.tgz", + "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "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": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "dependencies": { + "@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": ">=10" + } + }, + "node_modules/cross-env": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", + "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "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" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-inspect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.0.tgz", + "integrity": "sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "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/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", + "optional": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/d/node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "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/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": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "dev": true, + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deep-diff": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-1.0.2.tgz", + "integrity": "sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==", + "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==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "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/deepcopy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.1.0.tgz", + "integrity": "sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==", + "dependencies": { + "type-detect": "^4.0.8" + } + }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dev": true, + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/del/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "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/dependency-tree": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-9.0.0.tgz", + "integrity": "sha512-osYHZJ1fBSon3lNLw70amAXsQ+RGzXsPvk9HbBgTLbp/bQBmpH5mOmsUvqXU+YEWVU0ZLewsmzOET/8jWswjDQ==", + "dev": true, + "dependencies": { + "commander": "^2.20.3", + "debug": "^4.3.1", + "filing-cabinet": "^3.0.1", + "precinct": "^9.0.0", + "typescript": "^4.0.0" + }, + "bin": { + "dependency-tree": "bin/cli.js" + }, + "engines": { + "node": "^10.13 || ^12 || >=14" + } + }, + "node_modules/dependency-tree/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==", + "dev": true + }, + "node_modules/dependency-tree/node_modules/detective-stylus": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-3.0.0.tgz", + "integrity": "sha512-1xYTzbrduExqMYmte7Qk99IRA3Aa6oV7PYzd+3yDcQXkmENvyGF/arripri6lxRDdNYEb4fZFuHtNRAXbz3iAA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/dependency-tree/node_modules/module-definition": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-4.1.0.tgz", + "integrity": "sha512-rHXi/DpMcD2qcKbPCTklDbX9lBKJrUSl971TW5l6nMpqKCIlzJqmQ8cfEF5M923h2OOLHPDVlh5pJxNyV+AJlw==", + "dev": true, + "dependencies": { + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dependency-tree/node_modules/precinct": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-9.2.1.tgz", + "integrity": "sha512-uzKHaTyiVejWW7VJtHInb9KBUq9yl9ojxXGujhjhDmPon2wgZPBKQIKR+6csGqSlUeGXAA4MEFnU6DesxZib+A==", + "dev": true, + "dependencies": { + "@dependents/detective-less": "^3.0.1", + "commander": "^9.5.0", + "detective-amd": "^4.1.0", + "detective-cjs": "^4.1.0", + "detective-es6": "^3.0.1", + "detective-postcss": "^6.1.1", + "detective-sass": "^4.1.1", + "detective-scss": "^3.0.1", + "detective-stylus": "^3.0.0", + "detective-typescript": "^9.1.1", + "module-definition": "^4.1.0", + "node-source-walk": "^5.0.1" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.14.0 || >=16.0.0" + } + }, + "node_modules/dependency-tree/node_modules/precinct/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detective-amd": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-4.2.0.tgz", + "integrity": "sha512-RbuEJHz78A8nW7CklkqTzd8lDCN42En53dgEIsya0DilpkwslamSZDasLg8dJyxbw46OxhSQeY+C2btdSkCvQQ==", + "dev": true, + "dependencies": { + "ast-module-types": "^4.0.0", + "escodegen": "^2.0.0", + "get-amd-module-type": "^4.1.0", + "node-source-walk": "^5.0.1" + }, + "bin": { + "detective-amd": "bin/cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/detective-cjs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-4.1.0.tgz", + "integrity": "sha512-QxzMwt5MfPLwS7mG30zvnmOvHLx5vyVvjsAV6gQOyuMoBR5G1DhS1eJZ4P10AlH+HSnk93mTcrg3l39+24XCtg==", + "dev": true, + "dependencies": { + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/detective-es6": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-3.0.1.tgz", + "integrity": "sha512-evPeYIEdK1jK3Oji5p0hX4sPV/1vK+o4ihcWZkMQE6voypSW/cIBiynOLxQk5KOOQbdP8oOAsYqouMTYO5l1sw==", + "dev": true, + "dependencies": { + "node-source-walk": "^5.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/detective-less": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/detective-less/-/detective-less-1.0.2.tgz", + "integrity": "sha512-Rps1xDkEEBSq3kLdsdnHZL1x2S4NGDcbrjmd4q+PykK5aJwDdP5MBgrJw1Xo+kyUHuv3JEzPqxr+Dj9ryeDRTA==", + "dev": true, + "dependencies": { + "debug": "^4.0.0", + "gonzales-pe": "^4.2.3", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/detective-less/node_modules/node-source-walk": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.3.0.tgz", + "integrity": "sha512-8Q1hXew6ETzqKRAs3jjLioSxNfT1cx74ooiF8RlAONwVMcfq+UdzLC2eB5qcPldUxaE5w3ytLkrmV1TGddhZTA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/detective-postcss": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-6.1.3.tgz", + "integrity": "sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw==", + "dev": true, + "dependencies": { + "is-url": "^1.2.4", + "postcss": "^8.4.23", + "postcss-values-parser": "^6.0.2" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/detective-sass": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-4.1.3.tgz", + "integrity": "sha512-xGRbwGaGte57gvEqM8B9GDiURY3El/H49vA6g9wFkxq9zalmTlTAuqWu+BsH0iwonGPruLt55tZZDEZqPc6lag==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^5.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/detective-scss": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-3.1.1.tgz", + "integrity": "sha512-FWkfru1jZBhUeuBsOeGKXKAVDrzYFSQFK2o2tuG/nCCFQ0U/EcXC157MNAcR5mmj+mCeneZzlkBOFJTesDjrww==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^5.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/detective-stylus": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-2.0.1.tgz", + "integrity": "sha512-/Tvs1pWLg8eYwwV6kZQY5IslGaYqc/GACxjcaGudiNtN5nKCH6o2WnJK3j0gA3huCnoQcbv8X7oz/c1lnvE3zQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/detective-typescript": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-9.1.1.tgz", + "integrity": "sha512-Uc1yVutTF0RRm1YJ3g//i1Cn2vx1kwHj15cnzQP6ff5koNzQ0idc1zAC73ryaWEulA0ElRXFTq6wOqe8vUQ3MA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "^5.55.0", + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1", + "typescript": "^4.9.5" + }, + "engines": { + "node": "^12.20.0 || ^14.14.0 || >=16.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, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/downcache": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/downcache/-/downcache-0.0.9.tgz", + "integrity": "sha512-AssoVsNYu5DnPY0Ro67lkbiAr66sk5IHuiIGm3pzFzWmTzkcEoFjDlG8szzP4x+ZN2OHehKTZbwDrC7l2Q52+g==", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "graceful-fs": "^4.1.3", + "limiter": "^1.1.0", + "mkdirp": "^0.5.1", + "npmlog": "^2.0.3", + "request": "^2.69.0", + "rimraf": "^2.5.2" + } + }, + "node_modules/downcache/node_modules/gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", + "dev": true, + "dependencies": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, + "node_modules/downcache/node_modules/npmlog": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", + "integrity": "sha512-DaL6RTb8Qh4tMe2ttPT1qWccETy2Vi5/8p+htMpLBeXJTr2CAqnF5WQtSP2eFpvaNbhLZ5uilDb98mRm4Q+lZQ==", + "dev": true, + "dependencies": { + "ansi": "~0.3.1", + "are-we-there-yet": "~1.1.2", + "gauge": "~1.2.5" + } + }, + "node_modules/downcache/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/dset": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", + "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "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/duplexify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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/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/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.693", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.693.tgz", + "integrity": "sha512-/if4Ueg0GUQlhCrW2ZlXwDAm40ipuKo+OgeHInlL8sbjt+hzISxZK949fZeJaVsheamrzANXvw1zQTvbxTvSHw==" + }, + "node_modules/elegant-spinner": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-2.0.0.tgz", + "integrity": "sha512-5YRYHhvhYzV/FC4AiMdeSIg3jAYGq9xFvbhZMpPlJoBsfYgrw2DSCYeXfat6tYBu45PWiyRr3+flaCPPmviPaA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/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" + } + }, + "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/enhanced-resolve": { + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", + "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "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==", + "dev": true + }, + "node_modules/env-ci": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-5.5.0.tgz", + "integrity": "sha512-o0JdWIbOLP+WJKIUt36hz1ImQQFuN92nhsfTkHHap+J8CiI8WgGpH/a9jEGHh4/TU5BUUGjlnKXNoDb57+ne+A==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "fromentries": "^1.3.2", + "java-properties": "^1.0.0" + }, + "engines": { + "node": ">=10.17" + } + }, + "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": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es5-ext": { + "version": "0.10.63", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.63.tgz", + "integrity": "sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "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==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/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/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", + "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "dependencies": { + "@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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" + } + }, + "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==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/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": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/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": ">=7.0.0" + } + }, + "node_modules/eslint/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/eslint/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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/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==", + "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_modules/eslint/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==", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/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==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "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==", + "engines": { + "node": ">=4.0" + } + }, + "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==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/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==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "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==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "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==", + "engines": { + "node": ">=4.0" + } + }, + "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==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "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==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "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": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "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==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "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": { + "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": ">= 0.10.0" + } + }, + "node_modules/express-rate-limit": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.11.2.tgz", + "integrity": "sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw==", + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "express": "^4 || ^5" + } + }, + "node_modules/express/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": { + "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": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "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": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/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": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/express/node_modules/raw-body": { + "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.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "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/extract-files": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", + "integrity": "sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==", + "dev": true, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "funding": { + "url": "https://github.com/sponsors/jaydenseric" + } + }, + "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-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": { + "@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": ">=8.6.0" + } + }, + "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": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fast-xml-parser": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.5.tgz", + "integrity": "sha512-sWvP1Pl8H03B8oFJpFR3HE31HUfwtX7Rlf9BNsvdpujD4n7WMhfmu8h9wOV2u+c1k0ZilTADhPqypzx2J690ZQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "optional": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "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" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "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/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fetch-node-website": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/fetch-node-website/-/fetch-node-website-7.3.0.tgz", + "integrity": "sha512-/wayUHbdVUWrD72aqRNNrr6+MHnCkumZgNugN0RfiWJpbNJUdAkMk4Z18MGayGZVVqYXR1RWrV+bIFEt5HuBZg==", + "dev": true, + "dependencies": { + "cli-progress": "^3.11.2", + "colors-option": "^4.4.0", + "figures": "^5.0.0", + "got": "^12.3.1", + "is-plain-obj": "^4.1.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/fetch-node-website/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fetch-node-website/node_modules/figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fetch-node-website/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fetch-node-website/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-stream-rotator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", + "integrity": "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==", + "dependencies": { + "moment": "^2.29.1" + } + }, + "node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/filing-cabinet": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-3.3.1.tgz", + "integrity": "sha512-renEK4Hh6DUl9Vl22Y3cxBq1yh8oNvbAdXnhih0wVpmea+uyKjC9K4QeRjUaybIiIewdzfum+Fg15ZqJ/GyCaA==", + "dev": true, + "dependencies": { + "app-module-path": "^2.2.0", + "commander": "^2.20.3", + "debug": "^4.3.3", + "enhanced-resolve": "^5.8.3", + "is-relative-path": "^1.0.2", + "module-definition": "^3.3.1", + "module-lookup-amd": "^7.0.1", + "resolve": "^1.21.0", + "resolve-dependency-path": "^2.0.0", + "sass-lookup": "^3.0.0", + "stylus-lookup": "^3.0.1", + "tsconfig-paths": "^3.10.1", + "typescript": "^3.9.7" + }, + "bin": { + "filing-cabinet": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/filing-cabinet/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==", + "dev": true + }, + "node_modules/filing-cabinet/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.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==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/filter-obj": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz", + "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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": { + "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-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-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/find-cache-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/find-cache-dir/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-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/find-cache-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/find-cache-dir/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/find-cache-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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "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==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-versions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "dev": true, + "dependencies": { + "semver-regex": "^3.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/firebase-admin": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-12.0.0.tgz", + "integrity": "sha512-wBrrSSsKV++/+O8E7O/C7/wL0nbG/x4Xv4yatz/+sohaZ+LsnWtYUcrd3gZutO86hLpDex7xgyrkKbgulmtVyQ==", + "dependencies": { + "@fastify/busboy": "^1.2.1", + "@firebase/database-compat": "^1.0.2", + "@firebase/database-types": "^1.0.0", + "@types/node": "^20.10.3", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.0.1", + "node-forge": "^1.3.1", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.1.0", + "@google-cloud/storage": "^7.7.0" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "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==" + }, + "node_modules/flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.", + "dev": true + }, + "node_modules/flow-bin": { + "version": "0.119.1", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.119.1.tgz", + "integrity": "sha512-mX6qjJVi7aLqR9sDf8QIHt8yYEWQbkMLw7qFoC7sM/AbJwvqFm3pATPN96thsaL9o1rrshvxJpSgoj1PJSC3KA==", + "dev": true, + "bin": { + "flow": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/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, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.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": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "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/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" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "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/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "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": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "optional": true + }, + "node_modules/gauge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.1.tgz", + "integrity": "sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gaxios": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.3.0.tgz", + "integrity": "sha512-p+ggrQw3fBwH2F5N/PAI4k/G/y1art5OxKpb2J2chwNNHM4hHuAOtivjPuirMF4KNKwTTUal/lPfL2+7h2mEcg==", + "optional": true, + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "optional": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gaxios/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "optional": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gaxios/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/gaxios/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "node_modules/gaxios/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "node_modules/gaxios/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "optional": true, + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/generic-pool": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", + "engines": { + "node": ">= 4" + } + }, + "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==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-amd-module-type": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-4.1.0.tgz", + "integrity": "sha512-0e/eK6vTGCnSfQ6eYs3wtH05KotJYIP7ZIZEueP/KlA+0dIAEs8bYFvOd/U56w1vfjhJqBagUxVMyy9Tr/cViQ==", + "dev": true, + "dependencies": { + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "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/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "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_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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", + "dev": true, + "dependencies": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" + } + }, + "node_modules/git-log-parser/node_modules/split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "dev": true, + "dependencies": { + "through2": "~2.0.0" + } + }, + "node_modules/git-log-parser/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": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "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": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-cache-dir": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global-cache-dir/-/global-cache-dir-4.4.0.tgz", + "integrity": "sha512-bk0gI6IbbphRjAaCJJn5H+T/CcEck5B3a5KBO2BXSDzjFSV+API17w8GA7YPJ6IXJiasW8M0VsEIig1PCHdfOQ==", + "dev": true, + "dependencies": { + "cachedir": "^2.3.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/global-cache-dir/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "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==", + "engines": { + "node": ">=4" + } + }, + "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": { + "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" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/google-auth-library": { + "version": "9.6.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.6.3.tgz", + "integrity": "sha512-4CacM29MLC2eT9Cey5GDVK4Q8t+MMp8+OEdOaqD9MG6b0dOyLORaaeJMPQ7EESVgm/+z5EKYyFLxgzBJlJgyHQ==", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "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/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, + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-gax": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.1.tgz", + "integrity": "sha512-qpSfslpwqToIgQ+Tf3MjWIDjYK4UFIZ0uz6nLtttlW9N1NQA4PhGf9tlGo6KDYJ4rgL2w4CjXVd0z5yeNpN/Iw==", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "~1.10.0", + "@grpc/proto-loader": "^0.7.0", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.0", + "protobufjs": "7.2.6", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/google-gax/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "node_modules/google-gax/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "node_modules/google-gax/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/got": { + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.3.tgz", + "integrity": "sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true, + "engines": { + "node": ">= 14.17" + } + }, + "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==", + "dev": true + }, + "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==" + }, + "node_modules/graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-list-fields": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/graphql-list-fields/-/graphql-list-fields-2.0.4.tgz", + "integrity": "sha512-q3prnhAL/dBsD+vaGr83B8DzkBijg+Yh+lbt7qp2dW1fpuO+q/upzDXvFJstVsSAA8m11MHGkSxxyxXeLou4MA==" + }, + "node_modules/graphql-relay": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/graphql-relay/-/graphql-relay-0.10.0.tgz", + "integrity": "sha512-44yBuw2/DLNEiMypbNZBt1yMDbBmyVPVesPywnteGGALiBmdyy1JP8jSg8ClLePg8ZZxk0O4BLhd1a6U/1jDOQ==", + "engines": { + "node": "^12.20.0 || ^14.15.0 || >= 15.9.0" + }, + "peerDependencies": { + "graphql": "^16.2.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "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_modules/graphql-upload": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/graphql-upload/-/graphql-upload-15.0.2.tgz", + "integrity": "sha512-ufJAkZJBKWRDD/4wJR3VZMy9QWTwqIYIciPtCEF5fCNgWF+V1p7uIgz+bP2YYLiS4OJBhCKR8rnqE/Wg3XPUiw==", + "dependencies": { + "@types/busboy": "^1.5.0", + "@types/node": "*", + "@types/object-path": "^0.11.1", + "busboy": "^1.6.0", + "fs-capacitor": "^6.2.0", + "http-errors": "^2.0.0", + "object-path": "^0.11.8" + }, + "engines": { + "node": "^14.17.0 || ^16.0.0 || >= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/jaydenseric" + }, + "peerDependencies": { + "@types/express": "^4.0.29", + "@types/koa": "^2.11.4", + "graphql": "^16.3.0" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + }, + "@types/koa": { + "optional": true + } + } + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "optional": true, + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.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/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, + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "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" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/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==", + "engines": { + "node": ">=4" + } + }, + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/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": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dev": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hook-std": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", + "integrity": "sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/html-minifier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", + "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "dev": true, + "dependencies": { + "camel-case": "^3.0.0", + "clean-css": "^4.2.1", + "commander": "^2.19.0", + "he": "^1.2.0", + "param-case": "^2.1.1", + "relateurl": "^0.2.7", + "uglify-js": "^3.5.1" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/html-minifier/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==", + "dev": true + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/htmlparser2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-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/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==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "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": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "devOptional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true, + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "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": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb-keyval": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.0.tgz", + "integrity": "sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==", + "dependencies": { + "safari-14-idb-fix": "^3.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "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.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "engines": { + "node": ">= 4" + } + }, + "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==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "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/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "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": { + "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==", + "dev": true + }, + "node_modules/intersect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/intersect/-/intersect-1.0.1.tgz", + "integrity": "sha512-qsc720yevCO+4NydrJWgEWKccAQwTOvj2m73O/VBA6iUL2HGZJ9XqBiyraNrBXX/W1IAjdpXdRZk24sq8TzBRg==" + }, + "node_modules/into-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "dev": true, + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" + }, + "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": ">= 0.10" + } + }, + "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-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==", + "dev": true, + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-relative-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-relative-path/-/is-relative-path-1.0.2.tgz", + "integrity": "sha512-i1h+y50g+0hRbBD+dbnInl3JlJ702aar58snAeX+MxBAPvzXGej7sYoPMhlnykabt0ZzCJNBEyzMlekuQZN7fA==", + "dev": true + }, + "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": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-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/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": ">=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==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "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/issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "dependencies": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + }, + "engines": { + "node": ">=10.13" + } + }, + "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-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.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_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/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==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/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/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/jasmine": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.5.0.tgz", + "integrity": "sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==", + "dev": true, + "dependencies": { + "glob": "^7.1.4", + "jasmine-core": "~3.5.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + } + }, + "node_modules/jasmine-core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", + "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", + "dev": true + }, + "node_modules/jasmine-spec-reporter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", + "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", + "dev": true, + "dependencies": { + "colors": "1.4.0" + } + }, + "node_modules/java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/jose": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/jsdoc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdoc-babel": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.5.0.tgz", + "integrity": "sha512-PYfTbc3LNTeR8TpZs2M94NLDWqARq0r9gx3SvuziJfmJS7/AeMKvtj0xjzOX0R/4MOVA7/FqQQK7d6U0iEoztQ==", + "dev": true, + "dependencies": { + "jsdoc-regex": "^1.0.1", + "lodash": "^4.17.10" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/jsdoc-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz", + "integrity": "sha512-CMFgT3K8GbmChWEfLWe6jlv9x33E8wLPzBjxIlh/eHLMcnDF+TF3CL265ZGBe029o1QdFepwVrQu0WuqqNPncg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jsdoc/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/jsdoc/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "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==", + "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.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "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", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "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": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "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": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "dependencies": { + "jws": "^3.2.2", + "lodash": "^4.17.21", + "ms": "^2.1.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/jsprim/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/jsprim/node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/jssha": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", + "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==", + "engines": { + "node": "*" + } + }, + "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/jwks-rsa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "dependencies": { + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", + "debug": "^4.3.4", + "jose": "^4.14.6", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "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/keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "node_modules/ldapjs": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-3.0.7.tgz", + "integrity": "sha512-1ky+WrN+4CFMuoekUOv7Y1037XWdjKpu0xAPwSP+9KdvmV9PG+qOKlssDV6a+U32apwxdD3is/BZcWOYzN30cg==", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/messages": "^1.3.0", + "@ldapjs/protocol": "^1.2.1", + "abstract-logging": "^2.0.1", + "assert-plus": "^1.0.0", + "backoff": "^2.5.0", + "once": "^1.4.0", + "vasync": "^2.2.1", + "verror": "^1.10.1" + } + }, + "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==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "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/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/lint-staged": { + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.2.3.tgz", + "integrity": "sha512-dX5CeCIDtKoNv5IQpOMq/YUP8PXc58/QW+iWapv8KzgYcbgUWJwhPaFjX5aUS9pAa8cpGH7Jur3Puw3tugTGIg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "cosmiconfig": "^6.0.0", + "debug": "^4.1.1", + "dedent": "^0.7.0", + "execa": "^4.0.1", + "listr2": "2.0.1", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/lint-staged/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": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/lint-staged/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/lint-staged/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/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, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/lint-staged/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-2.0.1.tgz", + "integrity": "sha512-APezMtg3gQTamAgixvFKPpq8ipQJix5dJcEw4S+UzF4k5fNn1Bm0ssULO01ekr3PkDT/hoT0bMKBb8hNFDAl2g==", + "dev": true, + "dependencies": { + "@samverschueren/stream-to-observable": "^0.3.0", + "chalk": "^4.0.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "elegant-spinner": "^2.0.0", + "enquirer": "^2.3.5", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "pad": "^3.2.0", + "rxjs": "^6.5.5", + "through": "^2.3.8", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/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": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/listr2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/listr2/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/listr2/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2/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==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==", + "dev": true + }, + "node_modules/lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "optional": true + }, + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true + }, + "node_modules/lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", + "dev": true + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", + "dev": true + }, + "node_modules/lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", + "dev": true + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", + "dev": true + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "dev": true + }, + "node_modules/lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==", + "dev": true + }, + "node_modules/lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==", + "dev": true + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true + }, + "node_modules/log-symbols": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/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": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-update/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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/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.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/long": { + "version": "4.0.0", + "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/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "dev": true + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/lru-memoizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", + "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/madge": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/madge/-/madge-6.1.0.tgz", + "integrity": "sha512-irWhT5RpFOc6lkzGHKLihonCVgM0YtfNUh4IrFeW3EqHpnt/JHUG3z26j8PeJEktCGB4tmGOOOJi1Rl/ACWucQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.1", + "commander": "^7.2.0", + "commondir": "^1.0.1", + "debug": "^4.3.1", + "dependency-tree": "^9.0.0", + "detective-amd": "^4.0.1", + "detective-cjs": "^4.0.0", + "detective-es6": "^3.0.0", + "detective-less": "^1.0.2", + "detective-postcss": "^6.1.0", + "detective-sass": "^4.0.1", + "detective-scss": "^3.0.0", + "detective-stylus": "^2.0.1", + "detective-typescript": "^9.0.0", + "ora": "^5.4.1", + "pluralize": "^8.0.0", + "precinct": "^8.1.0", + "pretty-ms": "^7.0.1", + "rc": "^1.2.7", + "stream-to-array": "^2.3.0", + "ts-graphviz": "^1.5.0", + "walkdir": "^0.4.1" + }, + "bin": { + "madge": "bin/cli.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/pahen" + }, + "peerDependencies": { + "typescript": "^3.9.5 || ^4.9.5 || ^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/madge/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/madge/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": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/madge/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/madge/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/madge/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/madge/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/madge/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/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 + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "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 + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "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.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "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.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.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "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" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mock-files-adapter": { + "resolved": "spec/dependencies/mock-files-adapter", + "link": true + }, + "node_modules/mock-mail-adapter": { + "resolved": "spec/dependencies/mock-mail-adapter", + "link": true + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/module-definition": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-3.4.0.tgz", + "integrity": "sha512-XxJ88R1v458pifaSkPNLUTdSPNVGMP2SXVncVmApGO+gAfrLANiYe6JofymCzVceGOMwQE2xogxBSc8uB7XegA==", + "dev": true, + "dependencies": { + "ast-module-types": "^3.0.0", + "node-source-walk": "^4.0.0" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/module-definition/node_modules/ast-module-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-3.0.0.tgz", + "integrity": "sha512-CMxMCOCS+4D+DkOQfuZf+vLrSEmY/7xtORwdxs4wtcC1wVgvk2MqFFTwQCFhvWsI4KPU9lcWXPI8DgRiz+xetQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/module-definition/node_modules/node-source-walk": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.3.0.tgz", + "integrity": "sha512-8Q1hXew6ETzqKRAs3jjLioSxNfT1cx74ooiF8RlAONwVMcfq+UdzLC2eB5qcPldUxaE5w3ytLkrmV1TGddhZTA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/module-lookup-amd": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-7.0.1.tgz", + "integrity": "sha512-w9mCNlj0S8qviuHzpakaLVc+/7q50jl9a/kmJ/n8bmXQZgDPkQHnPBb8MUOYh3WpAYkXuNc2c+khsozhIp/amQ==", + "dev": true, + "dependencies": { + "commander": "^2.8.1", + "debug": "^4.1.0", + "glob": "^7.1.6", + "requirejs": "^2.3.5", + "requirejs-config-file": "^4.0.0" + }, + "bin": { + "lookup-amd": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/module-lookup-amd/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==", + "dev": true + }, + "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/mongodb": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.0.tgz", + "integrity": "sha512-g+GCMHN1CoRUA+wb1Agv0TI4YTSiWr42B5ulkiAfLLHitGK1R+PkSAf3Lr5rPZwi/3F04LiaZEW0Kxro9Fi2TA==", + "dependencies": { + "bson": "^5.5.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "@mongodb-js/saslprep": "^1.1.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.0.0", + "kerberos": "^1.0.0 || ^2.0.0", + "mongodb-client-encryption": ">=2.3.0 <3", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongodb-download-url": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mongodb-download-url/-/mongodb-download-url-1.4.1.tgz", + "integrity": "sha512-OC0EGXiYTwZNcLq2U7Hbt1MDSPQR57/Kput4+W0F2kwVOa0HwWW4oY6DS1gOLlIeVOsihRKKH9EPNnc/BxF7UA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "minimist": "^1.2.3", + "node-fetch": "^2.6.1", + "semver": "^7.1.1" + }, + "bin": { + "mongodb-download-url": "bin/mongodb-download-url.js" + } + }, + "node_modules/mongodb-download-url/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/mongodb-download-url/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/mongodb-download-url/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/mongodb-download-url/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/mongodb-runner": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/mongodb-runner/-/mongodb-runner-5.4.4.tgz", + "integrity": "sha512-bODXH7sOMRXbpVceIR8zLnEgg9kv1eXW60pxW5dfNShkjWd+7wmalJY/Dm9LG1tcL7+O5H7lTZH+s32IWg+FVA==", + "dev": true, + "dependencies": { + "@mongodb-js/mongodb-downloader": "^0.2.8", + "debug": "^4.3.4", + "mongodb": "^5.6.0", + "mongodb-connection-string-url": "^2.6.0", + "yargs": "^17.7.2" + }, + "bin": { + "mongodb-runner": "bin/runner.js" + } + }, + "node_modules/mongodb-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mongodb-runner/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": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/mongodb-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/mongodb-runner/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/mongodb-runner/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/mongodb-runner/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-runner/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": ">=12" + } + }, + "node_modules/mongodb-version-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mongodb-version-list/-/mongodb-version-list-1.0.0.tgz", + "integrity": "sha512-F3kIABEMNjg3ZAX4SRbO1QPmhpP4NX2IgJq+lcUKidducTOVJafXJ+E+pMkgpU0xumC8QYbIZJ+8y4GZys9E4g==", + "dev": true, + "dependencies": { + "cheerio": "^0.22.0", + "debug": "^2.2.0", + "downcache": "^0.0.9", + "fs-extra": "^1.0.0", + "minimist": "^1.1.1", + "semver": "^5.0.1" + }, + "bin": { + "mongodb-version-list": "bin/mongodb-version-list.js" + } + }, + "node_modules/mongodb-version-list/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/mongodb-version-list/node_modules/fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "node_modules/mongodb-version-list/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/mongodb-version-list/node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/mongodb-version-list/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/mongodb-version-list/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "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/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "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": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/negotiator": { + "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" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "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==", + "dev": true + }, + "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" + } + }, + "node_modules/node-fetch": { + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.10.tgz", + "integrity": "sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/node-source-walk": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-5.0.2.tgz", + "integrity": "sha512-Y4jr/8SRS5hzEdZ7SGuvZGwfORvNsSsNRwDXx5WisiqzsVfeftDvRgfeqWNgZvWSJbgubTRVRYBzK6UO+ErqjA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.21.4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/npm/-/npm-7.24.2.tgz", + "integrity": "sha512-120p116CE8VMMZ+hk8IAb1inCPk4Dj3VZw29/n2g6UI77urJKVYb7FZUDW8hY+EBnfsjI/2yrobBgFyzo7YpVQ==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/ci-detect", + "@npmcli/config", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/run-script", + "abbrev", + "ansicolors", + "ansistyles", + "archy", + "cacache", + "chalk", + "chownr", + "cli-columns", + "cli-table3", + "columnify", + "fastest-levenshtein", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minipass", + "minipass-pipeline", + "mkdirp", + "mkdirp-infer-owner", + "ms", + "node-gyp", + "nopt", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "npmlog", + "opener", + "pacote", + "parse-conflict-json", + "qrcode-terminal", + "read", + "read-package-json", + "read-package-json-fast", + "readdir-scoped-modules", + "rimraf", + "semver", + "ssri", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "dev": true, + "dependencies": { + "@isaacs/string-locale-compare": "*", + "@npmcli/arborist": "*", + "@npmcli/ci-detect": "*", + "@npmcli/config": "*", + "@npmcli/map-workspaces": "*", + "@npmcli/package-json": "*", + "@npmcli/run-script": "*", + "abbrev": "*", + "ansicolors": "*", + "ansistyles": "*", + "archy": "*", + "cacache": "*", + "chalk": "*", + "chownr": "*", + "cli-columns": "*", + "cli-table3": "*", + "columnify": "*", + "fastest-levenshtein": "*", + "glob": "*", + "graceful-fs": "*", + "hosted-git-info": "*", + "ini": "*", + "init-package-json": "*", + "is-cidr": "*", + "json-parse-even-better-errors": "*", + "libnpmaccess": "*", + "libnpmdiff": "*", + "libnpmexec": "*", + "libnpmfund": "*", + "libnpmhook": "*", + "libnpmorg": "*", + "libnpmpack": "*", + "libnpmpublish": "*", + "libnpmsearch": "*", + "libnpmteam": "*", + "libnpmversion": "*", + "make-fetch-happen": "*", + "minipass": "*", + "minipass-pipeline": "*", + "mkdirp": "*", + "mkdirp-infer-owner": "*", + "ms": "*", + "node-gyp": "*", + "nopt": "*", + "npm-audit-report": "*", + "npm-install-checks": "*", + "npm-package-arg": "*", + "npm-pick-manifest": "*", + "npm-profile": "*", + "npm-registry-fetch": "*", + "npm-user-validate": "*", + "npmlog": "*", + "opener": "*", + "pacote": "*", + "parse-conflict-json": "*", + "qrcode-terminal": "*", + "read": "*", + "read-package-json": "*", + "read-package-json-fast": "*", + "readdir-scoped-modules": "*", + "rimraf": "*", + "semver": "*", + "ssri": "*", + "tar": "*", + "text-table": "*", + "tiny-relative-date": "*", + "treeverse": "*", + "validate-npm-package-name": "*", + "which": "*", + "write-file-atomic": "*" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/npm/node_modules/@gar/promisify": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "2.9.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.0.1", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^1.0.2", + "@npmcli/metavuln-calculator": "^1.1.0", + "@npmcli/move-file": "^1.1.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^1.0.1", + "@npmcli/package-json": "^1.0.1", + "@npmcli/run-script": "^1.8.2", + "bin-links": "^2.2.1", + "cacache": "^15.0.3", + "common-ancestor-path": "^1.0.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.1.5", + "npm-pick-manifest": "^6.1.0", + "npm-registry-fetch": "^11.0.0", + "pacote": "^11.3.5", + "parse-conflict-json": "^1.1.1", + "proc-log": "^1.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "ssri": "^8.0.1", + "treeverse": "^1.0.4", + "walk-up-path": "^1.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/@npmcli/ci-detect": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ini": "^2.0.0", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^5.0.0", + "semver": "^7.3.4", + "walk-up-path": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/@npmcli/disparity-colors": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ansi-styles": "^4.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/npm/node_modules/@npmcli/git": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^1.3.2", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^6.1.1", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + } + }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "1.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "installed-package-contents": "index.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^7.1.6", + "minimatch": "^3.0.4", + "read-package-json-fast": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^15.0.5", + "pacote": "^11.1.11", + "semver": "^7.3.2" + } + }, + "node_modules/npm/node_modules/@npmcli/move-file": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.1" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "1.3.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "infer-owner": "^1.0.4" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "1.8.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^1.0.2", + "@npmcli/promise-spawn": "^1.3.2", + "node-gyp": "^7.1.0", + "read-package-json-fast": "^2.0.1" + } + }, + "node_modules/npm/node_modules/@tootallnate/once": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/npm/node_modules/agentkeepalive": { + "version": "4.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "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" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/ansicolors": { + "version": "0.3.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/ansistyles": { + "version": "0.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/are-we-there-yet": { + "version": "1.1.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/asap": { + "version": "2.0.6", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/asn1": { + "version": "0.2.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/npm/node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/aws4": { + "version": "1.11.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/npm/node_modules/bin-links": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^4.0.1", + "mkdirp": "^1.0.3", + "npm-normalize-package-bin": "^1.0.0", + "read-cmd-shim": "^2.0.0", + "rimraf": "^3.0.0", + "write-file-atomic": "^3.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm/node_modules/builtins": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/cacache": { + "version": "15.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^4.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^2.0.0", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/cli-table3": { + "version": "0.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/npm/node_modules/cli-table3/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cli-table3/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/clone": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mkdirp-infer-owner": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/color-support": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/npm/node_modules/colors": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/npm/node_modules/columnify": { + "version": "1.5.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "node_modules/npm/node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/dashdash": { + "version": "1.14.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.3.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/debuglog": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/defaults": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/npm/node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/npm/node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/dezalgo": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/diff": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/extend": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/extsprintf": { + "version": "1.3.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.12", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/forever-agent": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/gauge": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1 || ^2.0.0", + "strip-ansi": "^3.0.1 || ^4.0.0", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/getpass": { + "version": "0.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "7.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.8", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/har-schema": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/har-validator": { + "version": "5.1.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/has": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/npm/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/http-signature": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/humanize-ms": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/infer-owner": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/ini": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "2.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^8.1.5", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "^4.1.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ip": { + "version": "1.1.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^3.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/is-core-module": { + "version": "2.7.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/isstream": { + "version": "0.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/jsbn": { + "version": "0.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-schema": { + "version": "0.2.3", + "dev": true, + "inBundle": true + }, + "node_modules/npm/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/jsprim": { + "version": "1.4.1", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/npm/node_modules/just-diff": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "minipass": "^3.1.1", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/disparity-colors": "^1.0.1", + "@npmcli/installed-package-contents": "^1.0.7", + "binary-extensions": "^2.2.0", + "diff": "^5.0.0", + "minimatch": "^3.0.4", + "npm-package-arg": "^8.1.4", + "pacote": "^11.3.4", + "tar": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^2.3.0", + "@npmcli/ci-detect": "^1.3.0", + "@npmcli/run-script": "^1.8.4", + "chalk": "^4.1.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-package-arg": "^8.1.2", + "pacote": "^11.3.1", + "proc-log": "^1.0.0", + "read": "^1.0.7", + "read-package-json-fast": "^2.0.2", + "walk-up-path": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^2.5.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "6.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^11.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^11.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/run-script": "^1.8.3", + "npm-package-arg": "^8.1.0", + "pacote": "^11.2.6" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "normalize-package-data": "^3.0.2", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0", + "semver": "^7.1.3", + "ssri": "^8.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^11.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^11.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^2.0.7", + "@npmcli/run-script": "^1.8.4", + "json-parse-even-better-errors": "^2.3.1", + "semver": "^7.3.5", + "stringify-package": "^1.0.1" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "9.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/mime-db": { + "version": "1.49.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/mime-types": { + "version": "2.1.32", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.49.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "3.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "1.4.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-json-stream": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/mkdirp-infer-owner": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "0.0.8", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/negotiator": { + "version": "0.6.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "7.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/node-gyp/node_modules/gauge": { + "version": "2.7.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/npmlog": { + "version": "4.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "2.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "8.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^4.0.1", + "semver": "^7.3.4", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.6", + "ignore-walk": "^3.0.3", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "npm-packlist": "bin/index.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "6.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^4.0.0", + "npm-normalize-package-bin": "^1.0.1", + "npm-package-arg": "^8.1.2", + "semver": "^7.3.4" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "5.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^11.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "11.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^9.0.1", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/npmlog": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/npm/node_modules/npmlog/node_modules/are-we-there-yet": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/oauth-sign": { + "version": "0.9.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/opener": { + "version": "1.5.2", + "dev": true, + "inBundle": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/pacote": { + "version": "11.3.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^2.1.0", + "@npmcli/installed-package-contents": "^1.0.6", + "@npmcli/promise-spawn": "^1.2.0", + "@npmcli/run-script": "^1.8.2", + "cacache": "^15.0.5", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.3", + "mkdirp": "^1.0.3", + "npm-package-arg": "^8.0.1", + "npm-packlist": "^2.1.4", + "npm-pick-manifest": "^6.0.0", + "npm-registry-fetch": "^11.0.0", + "promise-retry": "^2.0.1", + "read-package-json-fast": "^2.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.1.0" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.0", + "just-diff": "^3.0.1", + "just-diff-apply": "^3.0.0" + } + }, + "node_modules/npm/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/performance-now": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/proc-log": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "0.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "1" + } + }, + "node_modules/npm/node_modules/psl": { + "version": "1.8.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/qs": { + "version": "6.5.2", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/npm/node_modules/read": { + "version": "1.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/read-package-json": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^3.0.0", + "npm-normalize-package-bin": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/npm/node_modules/request": { + "version": "2.88.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/npm/node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/semver": { + "version": "7.3.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.6.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "6.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.1", + "socks": "^2.6.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.10", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/sshpk": { + "version": "1.16.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ssri": { + "version": "8.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/stringify-package": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.1.11", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/treeverse": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "inBundle": true, + "license": "Unlicense" + }, + "node_modules/npm/node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/npm/node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/uuid": { + "version": "3.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/npm/node_modules/verror": { + "version": "1.10.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/npm/node_modules/which": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/wide-align": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/npm/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npmlog": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-7.0.1.tgz", + "integrity": "sha512-uJ0YFk/mCQpLBt+bxN88AKd+gyqZvZDbtiNxk6Waqcj2aPRyfVx8ITawkyQynxUagInjdYT1+qj4NfA5KJJUxg==", + "dependencies": { + "are-we-there-yet": "^4.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^5.0.0", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npmlog/node_modules/are-we-there-yet": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-4.0.2.tgz", + "integrity": "sha512-ncSWAawFhKMJDTdoAeOV+jyW1VCMj5QIAwULIBV0SSR7B/RLPPEQiknKcg/RIIZlUQrxELpsxMiTUoAQ4sIUyg==", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/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/nyc/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/nyc/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/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/nyc/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/nyc/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/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/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "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" + } + }, + "node_modules/object-path": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", + "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==", + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/onetime": { + "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" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optimism": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0.tgz", + "integrity": "sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ==", + "dev": true, + "dependencies": { + "@wry/caches": "^1.0.0", + "@wry/context": "^0.7.0", + "@wry/trie": "^0.4.3", + "tslib": "^2.3.0" + } + }, + "node_modules/optimism/node_modules/@wry/trie": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.4.3.tgz", + "integrity": "sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==", + "dev": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "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" + } + }, + "node_modules/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, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/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": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ora/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/otpauth": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/otpauth/-/otpauth-9.2.2.tgz", + "integrity": "sha512-2VcnYRUmq1dNckIfySNYP32ITWp1bvTeAEW0BSCR6G3GBf3a5zb9E+ubY62t3Dma9RjoHlvd7QpmzHfJZRkiNg==", + "dependencies": { + "jssha": "~3.3.1" + }, + "funding": { + "url": "https://github.com/hectorm/otpauth?sponsor=1" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-filter/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/pad": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/pad/-/pad-3.2.0.tgz", + "integrity": "sha512-2u0TrjcGbOjBTJpyewEl4hBO3OeX5wWue7eIFPzQTg6wFSvoaHcBTTUY5m+n0hd04gmTCPuY0kCpVIVuw5etwg==", + "dev": true, + "dependencies": { + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse/-/parse-5.0.0.tgz", + "integrity": "sha512-6gOARZWiHjmGusbTskhC1qlRn527olMEsdt2LLj9cP2GY3n4VFOwFwV8z/vm2+YfzPfPcv8z7qLih1NzmqzO0g==", + "dependencies": { + "@babel/runtime-corejs3": "7.23.2", + "idb-keyval": "6.2.1", + "react-native-crypto-js": "1.0.0", + "uuid": "9.0.1", + "ws": "8.16.0", + "xmlhttprequest": "1.8.0" + }, + "engines": { + "node": ">=18 <21" + }, + "optionalDependencies": { + "crypto-js": "4.2.0" + } + }, + "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/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse/node_modules/@babel/runtime-corejs3": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.2.tgz", + "integrity": "sha512-54cIh74Z1rp4oIjsHjqN+WM4fMyCBYe+LpZ9jWm51CZ1fbH3SkAzQD/3XLoNkjbJ7YEmjobLXyvQrFypRHOrXw==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/parse/node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "optional": true + }, + "node_modules/parse/node_modules/idb-keyval": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", + "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==" + }, + "node_modules/parse/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "engines": { + "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": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/pg": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-minify": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.3.tgz", + "integrity": "sha512-NoSsPqXxbkD8RIe+peQCqiea4QzXgosdTKY8p7PsbbGsh2F8TifDj/vJxfuR8qJwNYrijdSs7uf0tAe6WOyCsQ==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/pg-monitor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pg-monitor/-/pg-monitor-2.0.0.tgz", + "integrity": "sha512-UqjhroM701sRrJHhXeF1OwNBGxkN9R0YgkVU8A46wWn3RwK/K7QDylChMoDxo8TmGp86CBP4ZSf+RK9vD8XyVA==", + "dependencies": { + "cli-color": "2.0.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/pg-monitor/node_modules/cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pg-monitor/node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/pg-monitor/node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, + "node_modules/pg-pool": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-promise": { + "version": "11.5.4", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.5.4.tgz", + "integrity": "sha512-esYSkDt2h6NQOkfotGAm1Ld5OjoITJLpB88Z1PIlcAU/RQ0XQE2PxW0bLJEOMHPGV5iaRnj1Y7ARznXbgN4FNw==", + "dependencies": { + "assert-options": "0.8.1", + "pg": "8.11.3", + "pg-minify": "1.6.3", + "spex": "3.3.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pgpass/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-values-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz", + "integrity": "sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==", + "dev": true, + "dependencies": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.2.9" + } + }, + "node_modules/postcss-values-parser/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/precinct": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-8.3.1.tgz", + "integrity": "sha512-pVppfMWLp2wF68rwHqBIpPBYY8Kd12lDhk8LVQzOwqllifVR15qNFyod43YLyFpurKRZQKnE7E4pofAagDOm2Q==", + "dev": true, + "dependencies": { + "commander": "^2.20.3", + "debug": "^4.3.3", + "detective-amd": "^3.1.0", + "detective-cjs": "^3.1.1", + "detective-es6": "^2.2.1", + "detective-less": "^1.0.2", + "detective-postcss": "^4.0.0", + "detective-sass": "^3.0.1", + "detective-scss": "^2.0.1", + "detective-stylus": "^1.0.0", + "detective-typescript": "^7.0.0", + "module-definition": "^3.3.1", + "node-source-walk": "^4.2.0" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": "^10.13 || ^12 || >=14" + } + }, + "node_modules/precinct/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/precinct/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" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/precinct/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" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/precinct/node_modules/ast-module-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-3.0.0.tgz", + "integrity": "sha512-CMxMCOCS+4D+DkOQfuZf+vLrSEmY/7xtORwdxs4wtcC1wVgvk2MqFFTwQCFhvWsI4KPU9lcWXPI8DgRiz+xetQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/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==", + "dev": true + }, + "node_modules/precinct/node_modules/detective-amd": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-3.1.2.tgz", + "integrity": "sha512-jffU26dyqJ37JHR/o44La6CxtrDf3Rt9tvd2IbImJYxWKTMdBjctp37qoZ6ZcY80RHg+kzWz4bXn39e4P7cctQ==", + "dev": true, + "dependencies": { + "ast-module-types": "^3.0.0", + "escodegen": "^2.0.0", + "get-amd-module-type": "^3.0.0", + "node-source-walk": "^4.2.0" + }, + "bin": { + "detective-amd": "bin/cli.js" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/node_modules/detective-cjs": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-3.1.3.tgz", + "integrity": "sha512-ljs7P0Yj9MK64B7G0eNl0ThWSYjhAaSYy+fQcpzaKalYl/UoQBOzOeLCSFEY1qEBhziZ3w7l46KG/nH+s+L7BQ==", + "dev": true, + "dependencies": { + "ast-module-types": "^3.0.0", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/node_modules/detective-es6": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.2.tgz", + "integrity": "sha512-eZUKCUsbHm8xoeoCM0z6JFwvDfJ5Ww5HANo+jPR7AzkFpW9Mun3t/TqIF2jjeWa2TFbAiGaWESykf2OQp3oeMw==", + "dev": true, + "dependencies": { + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/node_modules/detective-postcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-4.0.0.tgz", + "integrity": "sha512-Fwc/g9VcrowODIAeKRWZfVA/EufxYL7XfuqJQFroBKGikKX83d2G7NFw6kDlSYGG3LNQIyVa+eWv1mqre+v4+A==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "is-url": "^1.2.4", + "postcss": "^8.1.7", + "postcss-values-parser": "^2.0.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/precinct/node_modules/detective-sass": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-3.0.2.tgz", + "integrity": "sha512-DNVYbaSlmti/eztFGSfBw4nZvwsTaVXEQ4NsT/uFckxhJrNRFUh24d76KzoCC3aarvpZP9m8sC2L1XbLej4F7g==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/node_modules/detective-scss": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-2.0.2.tgz", + "integrity": "sha512-hDWnWh/l0tht/7JQltumpVea/inmkBaanJUcXRB9kEEXVwVUMuZd6z7eusQ6GcBFrfifu3pX/XPyD7StjbAiBg==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/node_modules/detective-stylus": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-1.0.3.tgz", + "integrity": "sha512-4/bfIU5kqjwugymoxLXXLltzQNeQfxGoLm2eIaqtnkWxqbhap9puDVpJPVDx96hnptdERzS5Cy6p9N8/08A69Q==", + "dev": true + }, + "node_modules/precinct/node_modules/detective-typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-7.0.2.tgz", + "integrity": "sha512-unqovnhxzvkCz3m1/W4QW4qGsvXCU06aU2BAm8tkza+xLnp9SOFnob2QsTxUv5PdnQKfDvWcv9YeOeFckWejwA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "^4.33.0", + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.2.0", + "typescript": "^3.9.10" + }, + "engines": { + "node": "^10.13 || >=12.0.0" + } + }, + "node_modules/precinct/node_modules/detective-typescript/node_modules/ast-module-types": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-2.7.1.tgz", + "integrity": "sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw==", + "dev": true + }, + "node_modules/precinct/node_modules/get-amd-module-type": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-3.0.2.tgz", + "integrity": "sha512-PcuKwB8ouJnKuAPn6Hk3UtdfKoUV3zXRqVEvj8XGIXqjWfgd1j7QGdXy5Z9OdQfzVt1Sk29HVe/P+X74ccOuqw==", + "dev": true, + "dependencies": { + "ast-module-types": "^3.0.0", + "node-source-walk": "^4.2.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/node_modules/node-source-walk": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.3.0.tgz", + "integrity": "sha512-8Q1hXew6ETzqKRAs3jjLioSxNfT1cx74ooiF8RlAONwVMcfq+UdzLC2eB5qcPldUxaE5w3ytLkrmV1TGddhZTA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/precinct/node_modules/postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/precinct/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/process-warning": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", + "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", + "optional": true, + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "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/node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, + "node_modules/psl": { + "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==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", + "dev": true + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rate-limit-redis": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-3.0.2.tgz", + "integrity": "sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw==", + "engines": { + "node": ">= 14.5.0" + }, + "peerDependencies": { + "express-rate-limit": "^6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "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": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/react-native-crypto-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-native-crypto-js/-/react-native-crypto-js-1.0.0.tgz", + "integrity": "sha512-FNbLuG/HAdapQoybeZSoes1PWdOj0w242gb+e1R0hicf3Gyj/Mf8M9NaED2AnXVOX01b2FXomwUiw1xP1K+8sA==" + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/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/read-pkg-up/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/read-pkg-up/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/read-pkg-up/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/read-pkg-up/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": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/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==", + "dev": true + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/redis": { + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz", + "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==", + "workspaces": [ + "./packages/*" + ], + "dependencies": { + "@redis/bloom": "1.2.0", + "@redis/client": "1.5.14", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", + "@redis/time-series": "1.0.5" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", + "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", + "dev": true, + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/rehackt": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.0.5.tgz", + "integrity": "sha512-BI1rV+miEkaHj8zd2n+gaMgzu/fKz7BGlb4zZ6HAiY9adDmJMkaDcmuXlJFv0eyKUob+oszs3/2gdnXUrzx2Tg==", + "dev": true, + "peerDependencies": { + "@types/react": "*", + "react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 4" + } + }, + "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", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true, + "bin": { + "r_js": "bin/r.js", + "r.js": "bin/r.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/resolve-dependency-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz", + "integrity": "sha512-DIgu+0Dv+6v2XwRaNWnumKu7GPufBBOr5I1gRPJHkvghrfCGOooJODFvgFimX/KRxk9j0whD2MnKHzM1jYvk9w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/response-iterator": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/response-iterator/-/response-iterator-0.2.6.tgz", + "integrity": "sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "optional": true, + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/rxjs/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/safari-14-idb-fix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/safari-14-idb-fix/-/safari-14-idb-fix-3.0.0.tgz", + "integrity": "sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-stable-stringify": { + "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" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sass-lookup": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-3.0.0.tgz", + "integrity": "sha512-TTsus8CfFRn1N44bvdEai1no6PqdmDiQUiqW5DlpmtT+tYnIt1tXtDIph5KA1efC+LmioJXSnCtUVpcK9gaKIg==", + "dev": true, + "dependencies": { + "commander": "^2.16.0" + }, + "bin": { + "sass-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/sass-lookup/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==", + "dev": true + }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/seek-bzip/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==", + "dev": true + }, + "node_modules/semantic-release": { + "version": "17.4.6", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.4.6.tgz", + "integrity": "sha512-0B1OGkW8gzQjLbj3H5G4fJyy73HAWsoDnzWYyfNJHyyyLi1acQd+id4O7U+12wXTk9G83pXCgSFj9oYTvocFMA==", + "dev": true, + "dependencies": { + "@semantic-release/commit-analyzer": "^8.0.0", + "@semantic-release/error": "^2.2.0", + "@semantic-release/github": "^7.0.0", + "@semantic-release/npm": "^7.0.0", + "@semantic-release/release-notes-generator": "^9.0.0", + "aggregate-error": "^3.0.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.0.0", + "env-ci": "^5.0.0", + "execa": "^5.0.0", + "figures": "^3.0.0", + "find-versions": "^4.0.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^2.0.0", + "hosted-git-info": "^4.0.0", + "lodash": "^4.17.21", + "marked": "^2.0.0", + "marked-terminal": "^4.1.1", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "p-reduce": "^2.0.0", + "read-pkg-up": "^7.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^3.1.1", + "signale": "^1.2.1", + "yargs": "^16.2.0" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, + "engines": { + "node": ">=10.18" + } + }, + "node_modules/semantic-release/node_modules/@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "node_modules/semantic-release/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/semantic-release/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": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/semantic-release/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/semantic-release/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/semantic-release/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/semantic-release/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/semantic-release/node_modules/marked": { + "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": ">= 10" + } + }, + "node_modules/semantic-release/node_modules/marked-terminal": { + "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": "^4.3.1", + "cardinal": "^2.1.1", + "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" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/semantic-release/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semantic-release/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/semantic-release/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/semantic-release/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": { + "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/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true + }, + "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/semver-regex": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", + "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "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": "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": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "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/serve-static": { + "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.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==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/showdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", + "dev": true, + "dependencies": { + "commander": "^9.0.0" + }, + "bin": { + "showdown": "bin/showdown.js" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/tiviesantos" + } + }, + "node_modules/showdown/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "dev": true, + "dependencies": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signale/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi": { + "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", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "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", + "npm": ">= 3.0.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/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "dev": true + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spawn-wrap/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/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, + "node_modules/spex": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.3.0.tgz", + "integrity": "sha512-VNiXjFp6R4ldPbVRYbpxlD35yRHceecVXlct1J4/X80KuuPnW2AXMq3sGwhnJOhKkUsOxAT6nRGfGE5pocVw5w==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "optional": true + }, + "node_modules/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", + "dev": true, + "dependencies": { + "any-promise": "^1.1.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "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/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/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", + "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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stringify-object/node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, + "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-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "optional": true + }, + "node_modules/stylus-lookup": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-3.0.2.tgz", + "integrity": "sha512-oEQGHSjg/AMaWlKe7gqsnYzan8DLcGIHe0dUaFkucZZ14z4zjENRlQMCHT4FNsiWnJf17YN9OvrCfCoi7VvOyg==", + "dev": true, + "dependencies": { + "commander": "^2.8.1", + "debug": "^4.1.0" + }, + "bin": { + "stylus-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/stylus-lookup/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==", + "dev": true + }, + "node_modules/subscriptions-transport-ws": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz", + "integrity": "sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==", + "deprecated": "The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md", + "dependencies": { + "backo2": "^1.0.2", + "eventemitter3": "^3.1.0", + "iterall": "^1.2.1", + "symbol-observable": "^1.0.4", + "ws": "^5.2.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependencies": { + "graphql": "^15.7.2 || ^16.0.0" + } + }, + "node_modules/subscriptions-transport-ws/node_modules/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==", + "engines": { + "node": ">=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": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "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/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/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/teeny-request/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "node_modules/teeny-request/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "node_modules/teeny-request/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", + "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", + "dev": true, + "dependencies": { + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-decoding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz", + "integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==" + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/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==" + }, + "node_modules/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==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "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==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dependencies": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/tr46/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/traverse": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ts-graphviz": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-1.8.2.tgz", + "integrity": "sha512-5YhbFoHmjxa7pgQLkB07MtGnGJ/yhvjmc9uhsnDBEICME6gkPf83SBwLDQqGDoCa3XzUMWLk1AU2Wn1u1naDtA==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + } + }, + "node_modules/ts-invariant": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", + "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "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", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/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/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "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==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "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==", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/value-or-promise": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==", + "engines": { + "node": ">=12" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vasync": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-2.2.1.tgz", + "integrity": "sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "verror": "1.10.0" + } + }, + "node_modules/vasync/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/vasync/node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/verror/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/walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "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": { + "defaults": "^1.0.3" + } + }, + "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, + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "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==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "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/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/winston": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.12.0.tgz", + "integrity": "sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "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.7.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-daily-rotate-file": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-5.0.0.tgz", + "integrity": "sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw==", + "dependencies": { + "file-stream-rotator": "^0.6.1", + "object-hash": "^3.0.0", + "triple-beam": "^1.4.1", + "winston-transport": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "winston": "^3" + } + }, + "node_modules/winston-transport": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/winston/node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "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/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "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==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "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/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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": { + "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": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/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/yargs/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/yargs/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/yargs/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/yargs/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": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zen-observable": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", + "dev": true + }, + "node_modules/zen-observable-ts": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", + "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", + "dev": true, + "dependencies": { + "zen-observable": "0.8.15" + } + }, + "spec/dependencies/mock-files-adapter": { + "version": "1.0.0", + "dev": true + }, + "spec/dependencies/mock-mail-adapter": { + "version": "1.0.0", + "dev": true + } + }, "dependencies": { "@actions/core": { "version": "1.9.1", @@ -31,68 +19753,277 @@ "tunnel": "^0.0.6" } }, + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@apollo/cache-control-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@apollo/cache-control-types/-/cache-control-types-1.0.3.tgz", + "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==", + "requires": {} + }, "@apollo/client": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.6.1.tgz", - "integrity": "sha512-WGC7n2IS7GIbCCfVvu58Qncmj6qUBYbI/DxPVHGffDuY5y5l+OI2YIr5UXyR8+G9Ly1d6iYbX6l6l+Rw6F6gHA==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.9.5.tgz", + "integrity": "sha512-7y+c8MTPU+hhTwvcGVtMMGIgWduzrvG1mz5yJMRyqYbheBkkky3Lki6ADWVSBXG1lZoOtPYvB2zDgVfKb2HSsw==", "dev": true, "requires": { "@graphql-typed-document-node/core": "^3.1.1", - "@wry/context": "^0.6.0", - "@wry/equality": "^0.5.0", - "@wry/trie": "^0.3.0", + "@wry/caches": "^1.0.0", + "@wry/equality": "^0.5.6", + "@wry/trie": "^0.5.0", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.16.1", + "optimism": "^0.18.0", "prop-types": "^15.7.2", + "rehackt": "0.0.5", + "response-iterator": "^0.2.6", "symbol-observable": "^4.0.0", - "ts-invariant": "^0.10.0", + "ts-invariant": "^0.10.3", "tslib": "^2.3.0", - "use-sync-external-store": "^1.0.0", - "zen-observable-ts": "^1.2.0" + "zen-observable-ts": "^1.2.5" + } + }, + "@apollo/protobufjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", + "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", + "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", + "long": "^4.0.0" + } + }, + "@apollo/server": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-4.10.1.tgz", + "integrity": "sha512-XGMOgTyzV4EBHQq0xQVKFry9hZF7AA/6nxxGLamqdxodhdSdGbU9jrlb5/XDveeGuXP3+5JDdrB2HcziVLJcMA==", + "requires": { + "@apollo/cache-control-types": "^1.0.3", + "@apollo/server-gateway-interface": "^1.1.1", + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.createhash": "^2.0.0", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.isnodelike": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0", + "@apollo/utils.usagereporting": "^2.1.0", + "@apollo/utils.withrequired": "^2.0.0", + "@graphql-tools/schema": "^9.0.0", + "@josephg/resolvable": "^1.0.0", + "@types/express": "^4.17.13", + "@types/express-serve-static-core": "^4.17.30", + "@types/node-fetch": "^2.6.1", + "async-retry": "^1.2.1", + "cors": "^2.8.5", + "express": "^4.17.1", + "loglevel": "^1.6.8", + "lru-cache": "^7.10.1", + "negotiator": "^0.6.3", + "node-abort-controller": "^3.1.1", + "node-fetch": "^2.6.7", + "uuid": "^9.0.0", + "whatwg-mimetype": "^3.0.0" }, "dependencies": { - "@wry/equality": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.2.tgz", - "integrity": "sha512-oVMxbUXL48EV/C0/M7gLVsoK6qRHPS85x8zECofEZOVvxGmIPLA9o5Z27cc2PoAyZz1S2VoM2A7FLAnpfGlneA==", - "dev": true, + "@graphql-tools/schema": { + "version": "9.0.19", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.19.tgz", + "integrity": "sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==", "requires": { - "tslib": "^2.3.0" + "@graphql-tools/merge": "^8.4.1", + "@graphql-tools/utils": "^9.2.1", + "tslib": "^2.4.0", + "value-or-promise": "^1.0.12" } }, - "ts-invariant": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.1.tgz", - "integrity": "sha512-dOmY3naALBtNyK+nrVGzD8DVxSJ9OIHragItZ3XvxGORNAZL6uszgQYaD3PW+TPh2NWNsOpuQUxznuvTkmcdqw==", - "dev": true, + "@graphql-tools/utils": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", "requires": { - "tslib": "^2.1.0" + "@graphql-typed-document-node/core": "^3.1.1", + "tslib": "^2.4.0" } }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + }, + "node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, + "@apollo/server-gateway-interface": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@apollo/server-gateway-interface/-/server-gateway-interface-1.1.1.tgz", + "integrity": "sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==", + "requires": { + "@apollo/usage-reporting-protobuf": "^4.1.1", + "@apollo/utils.fetcher": "^2.0.0", + "@apollo/utils.keyvaluecache": "^2.1.0", + "@apollo/utils.logger": "^2.0.0" + } + }, + "@apollo/usage-reporting-protobuf": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.1.tgz", + "integrity": "sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==", + "requires": { + "@apollo/protobufjs": "1.2.7" + } + }, + "@apollo/utils.createhash": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.createhash/-/utils.createhash-2.0.1.tgz", + "integrity": "sha512-fQO4/ZOP8LcXWvMNhKiee+2KuKyqIcfHrICA+M4lj/h/Lh1H10ICcUtk6N/chnEo5HXu0yejg64wshdaiFitJg==", + "requires": { + "@apollo/utils.isnodelike": "^2.0.1", + "sha.js": "^2.4.11" + } + }, + "@apollo/utils.dropunuseddefinitions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-2.0.1.tgz", + "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==", + "requires": {} + }, + "@apollo/utils.fetcher": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.fetcher/-/utils.fetcher-2.0.1.tgz", + "integrity": "sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==" + }, + "@apollo/utils.isnodelike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.isnodelike/-/utils.isnodelike-2.0.1.tgz", + "integrity": "sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==" + }, + "@apollo/utils.keyvaluecache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-2.1.1.tgz", + "integrity": "sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==", + "requires": { + "@apollo/utils.logger": "^2.0.1", + "lru-cache": "^7.14.1" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" } } }, + "@apollo/utils.logger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-2.0.1.tgz", + "integrity": "sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==" + }, + "@apollo/utils.printwithreducedwhitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-2.0.1.tgz", + "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==", + "requires": {} + }, + "@apollo/utils.removealiases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-2.0.1.tgz", + "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==", + "requires": {} + }, + "@apollo/utils.sortast": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-2.0.1.tgz", + "integrity": "sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==", + "requires": { + "lodash.sortby": "^4.7.0" + } + }, + "@apollo/utils.stripsensitiveliterals": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-2.0.1.tgz", + "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==", + "requires": {} + }, + "@apollo/utils.usagereporting": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-2.1.0.tgz", + "integrity": "sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==", + "requires": { + "@apollo/usage-reporting-protobuf": "^4.1.0", + "@apollo/utils.dropunuseddefinitions": "^2.0.1", + "@apollo/utils.printwithreducedwhitespace": "^2.0.1", + "@apollo/utils.removealiases": "2.0.1", + "@apollo/utils.sortast": "^2.0.1", + "@apollo/utils.stripsensitiveliterals": "^2.0.1" + } + }, + "@apollo/utils.withrequired": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@apollo/utils.withrequired/-/utils.withrequired-2.0.1.tgz", + "integrity": "sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==" + }, "@babel/cli": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.10.0.tgz", - "integrity": "sha512-AziyYI4DpD4NmAcBD2xnH8CcIgdRrCGlW7wVL9Ysk736PCSNn2ZZedAUMu5rx/SfMT7Yv+3UReHcWKeQ3wNd/Q==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.9.tgz", + "integrity": "sha512-vB1UXmGDNEhcf1jNAHKT9IlYk1R+hehVTLFlCLHBi8gfuHQGP6uRjgXVYU0EVlI/qwAWpstqkBdf2aez3/z/5Q==", "dev": true, "requires": { - "chokidar": "^2.1.8", + "@jridgewell/trace-mapping": "^0.3.17", + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0", "commander": "^4.0.1", - "convert-source-map": "^1.1.0", + "convert-source-map": "^2.0.0", "fs-readdir-recursive": "^1.1.0", - "glob": "^7.0.0", - "lodash": "^4.17.13", + "glob": "^7.2.0", "make-dir": "^2.1.0", - "slash": "^2.0.0", - "source-map": "^0.5.0" + "slash": "^2.0.0" }, "dependencies": { "commander": { @@ -100,393 +20031,402 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true } } }, "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" } }, "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", - "dev": true + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==" }, "@babel/core": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.0.tgz", - "integrity": "sha512-FGgV2XyPoVtYDvbFXlukEWt13Afka4mBRQ2CoTsHxpgVGO6XfgtT6eI+WyjQRGGTL90IDkIVmme8riFCLZ8lUw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.10.0", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.10.0", - "@babel/parser": "^7.10.0", - "@babel/template": "^7.10.0", - "@babel/traverse": "^7.10.0", - "@babel/types": "^7.10.0", - "convert-source-map": "^1.7.0", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, - "@babel/generator": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", - "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", - "dev": true, + "@babel/eslint-parser": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", + "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", "requires": { - "@babel/types": "^7.15.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.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==" + } + } + }, + "@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "requires": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@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==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } } }, "@babel/helper-annotate-as-pure": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", - "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.22.5" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz", - "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/types": "^7.22.15" } }, "@babel/helper-compilation-targets": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", - "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "requires": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, "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.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz", - "integrity": "sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-member-expression-to-functions": "^7.15.0", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.0", - "@babel/helper-split-export-declaration": "^7.14.5" + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", + "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "regexpu-core": "^4.7.1" + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } } }, - "@babel/helper-explode-assignable-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz", - "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==", + "@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" } }, - "@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/types": "^7.14.5" - } + "@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" }, - "@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", - "dev": true, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "requires": { - "@babel/types": "^7.14.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", - "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.22.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", - "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, "requires": { - "@babel/types": "^7.15.0" + "@babel/types": "^7.23.0" } }, "@babel/helper-module-imports": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", - "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", - "dev": true, + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.22.15" } }, "@babel/helper-module-transforms": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", - "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", - "dev": true, + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.0", - "@babel/helper-simple-access": "^7.14.8", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/helper-optimise-call-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", - "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.22.5" } }, "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz", - "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "@babel/helper-wrap-function": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" } }, "@babel/helper-replace-supers": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", - "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.0", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" } }, "@babel/helper-simple-access": { - "version": "7.14.8", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", - "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "requires": { - "@babel/types": "^7.14.8" + "@babel/types": "^7.22.5" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz", - "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.22.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", - "dev": true, + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.22.5" } }, + "@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" + }, "@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", - "dev": true + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==" }, "@babel/helper-wrap-function": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz", - "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" } }, "@babel/helpers": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", - "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", "requires": { - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" } }, "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", - "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz", - "integrity": "sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", - "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", - "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==" }, - "@babel/plugin-proposal-json-strings": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" } }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-proposal-object-rest-spread": { @@ -500,81 +20440,83 @@ "@babel/plugin-transform-parameters": "^7.9.5" } }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } + "requires": {} }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "@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, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-proposal-private-methods": { + "@babel/plugin-syntax-class-static-block": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", - "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", - "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.8.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==", + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", + "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@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==", + "@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@babel/plugin-syntax-flow": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", - "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "@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, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-json-strings": { @@ -586,6 +20528,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@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", @@ -631,500 +20582,736 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-syntax-top-level-await": { + "@babel/plugin-syntax-private-property-in-object": { "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==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" } }, + "@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, "@babel/plugin-transform-arrow-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5" + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", - "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@babel/plugin-transform-classes": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz", - "integrity": "sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A==", + "@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" } }, "@babel/plugin-transform-destructuring": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", - "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", - "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz", - "integrity": "sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", + "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-flow": "^7.8.3" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.23.3" } }, "@babel/plugin-transform-for-of": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz", - "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" } }, "@babel/plugin-transform-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", - "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-transform-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", - "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", - "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz", - "integrity": "sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.15.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.14.8", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz", - "integrity": "sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.5", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", - "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", - "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-new-target": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", - "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz", + "integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" } }, "@babel/plugin-transform-object-super": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-transform-parameters": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz", - "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@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, + "peer": true, + "requires": { + "@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" + }, + "dependencies": { + "@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, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + } } }, "@babel/plugin-transform-regenerator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", "dev": true, "requires": { - "regenerator-transform": "^0.14.2" + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", - "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-spread": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz", - "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-template-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", - "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@babel/preset-env": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.0.tgz", - "integrity": "sha512-UOZNyiZRvIGvIudjCB8Y8OVkpAvlslec4qgwC73yEvx3Puz0c/xc28Yru36y5K+StOkPPM+VldTsmXPht5LpSg==", + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", "dev": true, "requires": { - "@babel/compat-data": "^7.10.0", - "@babel/helper-compilation-targets": "^7.10.0", - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-proposal-async-generator-functions": "^7.8.3", - "@babel/plugin-proposal-class-properties": "^7.8.3", - "@babel/plugin-proposal-dynamic-import": "^7.8.3", - "@babel/plugin-proposal-json-strings": "^7.10.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-proposal-numeric-separator": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.10.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", - "@babel/plugin-proposal-optional-chaining": "^7.10.0", - "@babel/plugin-proposal-private-methods": "^7.8.3", - "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.8.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.8.3", - "@babel/plugin-transform-async-to-generator": "^7.8.3", - "@babel/plugin-transform-block-scoped-functions": "^7.8.3", - "@babel/plugin-transform-block-scoping": "^7.10.0", - "@babel/plugin-transform-classes": "^7.9.5", - "@babel/plugin-transform-computed-properties": "^7.8.3", - "@babel/plugin-transform-destructuring": "^7.10.0", - "@babel/plugin-transform-dotall-regex": "^7.8.3", - "@babel/plugin-transform-duplicate-keys": "^7.8.3", - "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.10.0", - "@babel/plugin-transform-function-name": "^7.8.3", - "@babel/plugin-transform-literals": "^7.8.3", - "@babel/plugin-transform-member-expression-literals": "^7.8.3", - "@babel/plugin-transform-modules-amd": "^7.9.6", - "@babel/plugin-transform-modules-commonjs": "^7.9.6", - "@babel/plugin-transform-modules-systemjs": "^7.10.0", - "@babel/plugin-transform-modules-umd": "^7.9.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.8.3", - "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.9.5", - "@babel/plugin-transform-property-literals": "^7.8.3", - "@babel/plugin-transform-regenerator": "^7.8.7", - "@babel/plugin-transform-reserved-words": "^7.8.3", - "@babel/plugin-transform-shorthand-properties": "^7.8.3", - "@babel/plugin-transform-spread": "^7.10.0", - "@babel/plugin-transform-sticky-regex": "^7.8.3", - "@babel/plugin-transform-template-literals": "^7.8.3", - "@babel/plugin-transform-typeof-symbol": "^7.8.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.0", - "@babel/plugin-transform-unicode-regex": "^7.8.3", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.10.0", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/preset-env": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", + "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@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-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.8", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.24.0", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" }, "dependencies": { + "@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-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==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } }, "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" } }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, "@babel/runtime": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz", - "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + } } }, "@babel/runtime-corejs3": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz", - "integrity": "sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.21.0.tgz", + "integrity": "sha512-TDD4UJzos3JJtM+tHX+w2Uc+KWj7GV+VKKFdMVd2Rx8sdA19hcc3P3AHFYd5LVOw+pYuSd5lICC3gm52B6Rwxw==", "requires": { - "core-js-pure": "^3.15.0", - "regenerator-runtime": "^0.13.4" + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", - "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" } }, "@babel/traverse": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", - "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.15.0", - "@babel/types": "^7.15.0", - "debug": "^4.1.0", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", "globals": "^11.1.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 - } } }, "@babel/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", - "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "requires": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -1133,89 +21320,264 @@ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" }, - "@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "@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" + } + }, + "@dependents/detective-less": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-3.0.2.tgz", + "integrity": "sha512-1YUvQ+e0eeTWAHoN8Uz2x2U37jZs6IGutiIE5LXId7cxfUGhtZjzxE06FdUiuiRrW+UE0vNCdSNPH2lY4dQCOQ==", + "dev": true, + "requires": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^5.0.1" + } + }, + "@eslint/eslintrc": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.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": { + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "requires": { + "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==" + } + } + }, + "@fastify/busboy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz", + "integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==", + "requires": { + "text-decoding": "^1.0.0" + } + }, + "@firebase/app-check-interop-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", + "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" + }, + "@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" + }, + "@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" + }, + "@firebase/component": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", + "integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==", + "requires": { + "@firebase/util": "1.9.4", + "tslib": "^2.1.0" + } + }, + "@firebase/database": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.3.tgz", + "integrity": "sha512-9fjqLt9JzL46gw9+NRqsgQEMjgRwfd8XtzcKqG+UYyhVeFCdVRQ0Wp6Dw/dvYHnbH5vNEKzNv36dcB4p+PIAAA==", + "requires": { + "@firebase/app-check-interop-types": "0.3.0", + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.5", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.4", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "@firebase/database-compat": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.3.tgz", + "integrity": "sha512-7tHEOcMbK5jJzHWyphPux4osogH/adWwncxdMxdBpB9g1DNIyY4dcz1oJdlkXGM/i/AjUBesZsd5CuwTRTBNTw==", + "requires": { + "@firebase/component": "0.6.5", + "@firebase/database": "1.0.3", + "@firebase/database-types": "1.0.1", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.4", + "tslib": "^2.1.0" + } + }, + "@firebase/database-types": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.1.tgz", + "integrity": "sha512-Tmcmx5XgiI7UVF/4oGg2P3AOTfq3WKEPsm2yf+uXtN7uG/a4WTWhVMrXGYRY2ZUL1xPxv9V33wQRJ+CcrUhVXw==", + "requires": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.4" + } + }, + "@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", + "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" + "tslib": "^2.1.0" } }, - "@envelop/core": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@envelop/core/-/core-2.3.2.tgz", - "integrity": "sha512-NTVY7bajznZyE0S/yzwIu5aimcM8JLqdeWkWUmwmrAHZdE6zjrvOuVCwq1kMIHzgV3bmLdPg2F7534Nxad/HLg==", + "@google-cloud/firestore": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.3.1.tgz", + "integrity": "sha512-YluLZbJK3dHXq6Ns5URCtr6hjBiG+6EM17QSivjaozPYDsv1R9a9mkWPz+jCQrb6Ewz6mxp3zavu6DXxvmSWLA==", + "optional": true, "requires": { - "@envelop/types": "2.2.0" + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.0.4", + "protobufjs": "^7.2.5" } }, - "@envelop/parser-cache": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@envelop/parser-cache/-/parser-cache-4.3.2.tgz", - "integrity": "sha512-gdi814GdJ8PazYBGtWcpKdqtbBbxhbdXBKhSpTjt1kNmgzBsKV1VV2J674/9UqwFjhpuk2POXouIwF0t3z6mXg==", + "@google-cloud/paginator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz", + "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==", + "optional": true, "requires": { - "tiny-lru": "7.0.6" + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "optional": true + } } }, - "@envelop/types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@envelop/types/-/types-2.2.0.tgz", - "integrity": "sha512-Lghvfs0kh53G5mUKpCMlB/FhHh3O8SSR4hewB7JyE9hOEu/9h/6u+GHH/OEgdaRHky1Sae5Jf4grO+h21ka4ig==" + "@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "optional": true }, - "@envelop/validation-cache": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@envelop/validation-cache/-/validation-cache-4.3.2.tgz", - "integrity": "sha512-dihBgqbwm52u69QQeyOZQyDeIz/GIlLuSmgVJcsrKbbevX6pqiuZAs7Vbaj8EraIkuhAqPInzKrtWqYRgePIOA==", + "@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "optional": true + }, + "@google-cloud/storage": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.7.0.tgz", + "integrity": "sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==", + "optional": true, "requires": { - "tiny-lru": "7.0.6" + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "compressible": "^2.0.12", + "duplexify": "^4.0.0", + "ent": "^2.2.0", + "fast-xml-parser": "^4.3.0", + "gaxios": "^6.0.2", + "google-auth-library": "^9.0.0", + "mime": "^3.0.0", + "mime-types": "^2.0.8", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.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 + } } }, "@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==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.4.1.tgz", + "integrity": "sha512-hssnPpZ818mxgl5+GfyOOSnnflAxiaTn1A1AojZcIbh4J52sS1Q0gSuBR5VrnUDjuxiqoCotpXdAQl+K+U6KLQ==", "requires": { - "@graphql-tools/utils": "8.12.0", + "@graphql-tools/utils": "^9.2.1", "tslib": "^2.4.0" }, "dependencies": { "@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==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz", + "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", "requires": { + "@graphql-typed-document-node/core": "^3.1.1", "tslib": "^2.4.0" } } } }, "@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==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.3.tgz", + "integrity": "sha512-p28Oh9EcOna6i0yLaCFOnkcBDQECVf3SCexT6ktb86QNj9idnkhI+tCxnwZDh58Qvjd2nURdkbevvoZkvxzCog==", "requires": { - "@graphql-tools/merge": "8.3.6", - "@graphql-tools/utils": "8.12.0", + "@graphql-tools/merge": "^9.0.3", + "@graphql-tools/utils": "^10.0.13", "tslib": "^2.4.0", - "value-or-promise": "1.0.11" + "value-or-promise": "^1.0.12" }, "dependencies": { "@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==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.3.tgz", + "integrity": "sha512-FeKv9lKLMwqDu0pQjPpF59GY3HReUkWXKsMIuMuJQOKh9BETu7zPEFUELvcw8w+lwZkl4ileJsHXC9+AnsT2Lw==", "requires": { - "@graphql-tools/utils": "8.12.0", + "@graphql-tools/utils": "^10.0.13", "tslib": "^2.4.0" } }, "@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==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.1.0.tgz", + "integrity": "sha512-wLPqhgeZ9BZJPRoaQbsDN/CtJDPd/L4qmmtPkjI3NuYJ39x+Eqz1Sh34EAGMuDh+xlOHqBwHczkZUpoK9tvzjw==", "requires": { + "@graphql-typed-document-node/core": "^3.1.1", + "cross-inspect": "1.0.0", + "dset": "^3.1.2", "tslib": "^2.4.0" } } @@ -1232,109 +21594,132 @@ "@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==" + "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==", + "requires": {} }, - "@graphql-yoga/common": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@graphql-yoga/common/-/common-2.6.0.tgz", - "integrity": "sha512-iG33wMQlBujB1+Q2D/CLEVDW3xTeBVhHKsbaUmVSHV4zpmGRRQMg/YROJ2mU1lONOyZDPIC+9j3AR7+x0dSzoA==", - "requires": { - "@envelop/core": "^2.0.0", - "@envelop/parser-cache": "^4.0.0", - "@envelop/validation-cache": "^4.0.0", - "@graphql-tools/schema": "^8.3.1", - "@graphql-tools/utils": "^8.6.0", - "@graphql-typed-document-node/core": "^3.1.1", - "@graphql-yoga/subscription": "2.0.0", - "cross-undici-fetch": "^0.4.2", - "dset": "^3.1.1", - "tslib": "^2.3.1" + "@grpc/grpc-js": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.1.tgz", + "integrity": "sha512-55ONqFytZExfOIjF1RjXPcVmT/jJqFzbbDqxK9jmRV4nxiYWtL9hENSW1Jfx0SdZfrvoqd44YJ/GJTqfRrawSQ==", + "optional": true, + "requires": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + } + }, + "@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "optional": true, + "requires": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" }, "dependencies": { - "@graphql-tools/merge": { - "version": "8.2.11", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.11.tgz", - "integrity": "sha512-fsjJVdsk9GV1jj1Ed2AKLlHYlsf0ZadTK8X5KxFRE1ZSnKqh56BLVX93JrtOIAnsiHkwOK2TC43HGhApF1swpQ==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "optional": true, "requires": { - "@graphql-tools/utils": "8.6.10", - "tslib": "~2.4.0" + "color-convert": "^2.0.1" } }, - "@graphql-tools/schema": { - "version": "8.3.11", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.3.11.tgz", - "integrity": "sha512-esMEnbyXbp8B5VEI4o395+x0G7Qmz3JSX5onFBF8HeLYcqWJasY5vBuWkO18VxrZpEnvnryodP6Y00bVag9O3Q==", + "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==", + "optional": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "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==", + "optional": true, "requires": { - "@graphql-tools/merge": "8.2.11", - "@graphql-tools/utils": "8.6.10", - "tslib": "~2.4.0", - "value-or-promise": "1.0.11" + "color-name": "~1.1.4" } }, - "@graphql-tools/utils": { - "version": "8.6.10", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.10.tgz", - "integrity": "sha512-bJH9qwuyM3BP0PTU6/lvBDkk6jdEIOn+dbyk4pHMVNnvbJ1gZQwo62To8SHxxaUTus8OMhhVPSh9ApWXREURcg==", + "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==", + "optional": true + }, + "long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "optional": true, "requires": { - "tslib": "~2.4.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "optional": true }, - "value-or-promise": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", - "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==" - } - } - }, - "@graphql-yoga/node": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@graphql-yoga/node/-/node-2.6.0.tgz", - "integrity": "sha512-VkHaiIwDYx+WJI/NnT2x+mGknk1YoNTP/auweDvKzPXdsWR5Za8rEYUloKZX4TxHTpyqbBLMtCt+4TDITriVbA==", - "requires": { - "@envelop/core": "^2.0.0", - "@graphql-tools/utils": "^8.6.0", - "@graphql-yoga/common": "2.6.0", - "@graphql-yoga/subscription": "2.0.0", - "cross-undici-fetch": "^0.4.2", - "tslib": "^2.3.1" - }, - "dependencies": { - "@graphql-tools/utils": { - "version": "8.6.10", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.10.tgz", - "integrity": "sha512-bJH9qwuyM3BP0PTU6/lvBDkk6jdEIOn+dbyk4pHMVNnvbJ1gZQwo62To8SHxxaUTus8OMhhVPSh9ApWXREURcg==", + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "optional": true, "requires": { - "tslib": "~2.4.0" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" } }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "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==", + "optional": true } } }, - "@graphql-yoga/subscription": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@graphql-yoga/subscription/-/subscription-2.0.0.tgz", - "integrity": "sha512-HlG+gIddjIP3/BDrMZymdzmzDjNdYuSGMxx6+1JA83gAEVRDR4yOoT4QeNKYqRhLK9xca/Hxp1PfBpquSa244Q==", + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "requires": { - "@repeaterjs/repeater": "^3.0.4", - "tslib": "^2.3.1" - }, - "dependencies": { - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - } + "@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==" + }, + "@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==" + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1348,6 +21733,62 @@ "resolve-from": "^5.0.0" }, "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "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" + } + }, + "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==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^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" + } + }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -1362,75 +21803,208 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "@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==" + }, + "@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==", + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@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==" + }, + "@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==" + }, + "@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==" + }, + "@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==", + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@jsdoc/salty": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.5.tgz", + "integrity": "sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "lodash": "^4.17.21" + } + }, + "@ldapjs/asn1": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-2.0.0.tgz", + "integrity": "sha512-G9+DkEOirNgdPmD0I8nu57ygQJKOOgFEMKknEuQvIHbGLwP3ny1mY+OTUYLCbCaGJP4sox5eYgBJRuSUpnAddA==" + }, + "@ldapjs/attribute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/attribute/-/attribute-1.0.0.tgz", + "integrity": "sha512-ptMl2d/5xJ0q+RgmnqOi3Zgwk/TMJYG7dYMC0Keko+yZU6n+oFM59MjQOUht5pxJeS4FWrImhu/LebX24vJNRQ==", + "requires": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "@ldapjs/change": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/change/-/change-1.0.0.tgz", + "integrity": "sha512-EOQNFH1RIku3M1s0OAJOzGfAohuFYXFY4s73wOhRm4KFGhmQQ7MChOh2YtYu9Kwgvuq1B0xKciXVzHCGkB5V+Q==", + "requires": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0" + } + }, + "@ldapjs/controls": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/controls/-/controls-2.1.0.tgz", + "integrity": "sha512-2pFdD1yRC9V9hXfAWvCCO2RRWK9OdIEcJIos/9cCVP9O4k72BY1bLDQQ4KpUoJnl4y/JoD4iFgM+YWT3IfITWw==", + "requires": { + "@ldapjs/asn1": "^1.2.0", + "@ldapjs/protocol": "^1.2.1" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "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" - } - }, - "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==", + "@ldapjs/asn1": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-1.2.0.tgz", + "integrity": "sha512-KX/qQJ2xxzvO2/WOvr1UdQ+8P5dVvuOLk/C9b1bIkXxZss8BaR28njXdPgFCpj5aHaf1t8PmuVnea+N9YG9YMw==" + } + } + }, + "@ldapjs/dn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/dn/-/dn-1.1.0.tgz", + "integrity": "sha512-R72zH5ZeBj/Fujf/yBu78YzpJjJXG46YHFo5E4W1EqfNpo1UsVPqdLrRMXeKIsJT3x9dJVIfR6OpzgINlKpi0A==", + "requires": { + "@ldapjs/asn1": "2.0.0", + "process-warning": "^2.1.0" + } + }, + "@ldapjs/filter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ldapjs/filter/-/filter-2.1.1.tgz", + "integrity": "sha512-TwPK5eEgNdUO1ABPBUQabcZ+h9heDORE4V9WNZqCtYLKc06+6+UAJ3IAbr0L0bYTnkkWC/JEQD2F+zAFsuikNw==", + "requires": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "@ldapjs/messages": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ldapjs/messages/-/messages-1.3.0.tgz", + "integrity": "sha512-K7xZpXJ21bj92jS35wtRbdcNrwmxAtPwy4myeh9duy/eR3xQKvikVycbdWVzkYEAVE5Ce520VXNOwCHjomjCZw==", + "requires": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.2.0" + } + }, + "@ldapjs/protocol": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ldapjs/protocol/-/protocol-1.2.1.tgz", + "integrity": "sha512-O89xFDLW2gBoZWNXuXpBSM32/KealKCTb3JGtJdtUQc7RjAk8XzrRgyz02cPAwGKwKPxy0ivuC7UP9bmN87egQ==" + }, + "@mongodb-js/mongodb-downloader": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-downloader/-/mongodb-downloader-0.2.8.tgz", + "integrity": "sha512-y+mgw9QspvgTLRNHZJRS+DUTPk45RWpvYD1MaGDWhZ4ajffvxGqanY+Z4R6z01n+tIRmQvpShzF6zk+2Pr9d6w==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "decompress": "^4.2.1", + "mongodb-download-url": "^1.3.0", + "node-fetch": "^2.6.11", + "tar": "^6.1.15" + }, + "dependencies": { + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "requires": { - "color-name": "~1.1.4" + "whatwg-url": "^5.0.0" } }, - "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==", + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } } } }, + "@mongodb-js/saslprep": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz", + "integrity": "sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "@napi-rs/triples": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@napi-rs/triples/-/triples-1.0.3.tgz", - "integrity": "sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/triples/-/triples-1.1.0.tgz", + "integrity": "sha512-XQr74QaLeMiqhStEhLn1im9EOMnkypp7MZOwQhGzqp2Weu5eQJbpPxWxixxlYRKWPOmJjsk6qYfYH9kq43yc2w==", + "optional": true + }, + "@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, "optional": true }, + "@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "requires": { + "eslint-scope": "5.1.1" + } + }, "@node-rs/bcrypt": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.1.0.tgz", @@ -1450,73 +22024,72 @@ } }, "@node-rs/bcrypt-android-arm64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.4.1.tgz", - "integrity": "sha512-CP/8CbrhLUjHW2OrOd6tgcx2FKMTWqUDAUCDtUq4ZBlUIn7P/e+/iosNK9QNBcT8AUMNr4TD1n5QW+SKM2Zk/Q==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.6.1.tgz", + "integrity": "sha512-KGpWqSKKIKoKrW1QnzY7ihZREMiPXrMO7ps+3vtLdyiRBqigj10TB/zjolbomZAkb/53jhFkIJpYQkbK5hqh0Q==", "optional": true }, "@node-rs/bcrypt-darwin-arm64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.4.1.tgz", - "integrity": "sha512-6Digb49rzOS36X6qXaU4a6JxDsxPlWj09AFyF/kBhhmRocDKHyO2dnR8vexhjlzLyMlS00VL2q8kPei2Q8IAYQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.6.1.tgz", + "integrity": "sha512-iUfuCYzqJTvi36ZEcEOgphb0C+4qI5aP+nIKsg/YEnerhbCKNRxhQXoxW1bayohpqjlenZ4jOKZXi1h2stMgPQ==", "optional": true }, "@node-rs/bcrypt-darwin-x64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.4.1.tgz", - "integrity": "sha512-Rs/ySQ0CHRXJCOrSWod0b4fmF3Z+EP4RygSXBsV/NTVggHB2TrSdHRYajG9ZHB7P0acs2HHb1GcP5jOpggpMvA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.6.1.tgz", + "integrity": "sha512-AQjjVgv5Z2jw8Krv8zbqxSgse6zBIYAnjVBHd74oEPDvdZcXomNc7Pv8eOletPAHRYaGcA2lrCBNEp5Un7ddsA==", "optional": true }, "@node-rs/bcrypt-linux-arm-gnueabihf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.4.1.tgz", - "integrity": "sha512-oiRR4vJUtwO2DG91oyWDHYx9oU79190l0FIgYKwfXjt9ge5ZFr+fVjXbayuANxWCAtt178u3HYwWR1ayHhRpUQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.6.1.tgz", + "integrity": "sha512-Hpy0pEXrxmIe0IYdWaH4vIka6xk2s4TdrnmQaPR7wSMfBQlGpyBXmgfCtPmGER/pb5Ft9H6q2l3Sh0w24X0PLQ==", "optional": true }, "@node-rs/bcrypt-linux-arm64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.4.1.tgz", - "integrity": "sha512-oA/WNbHZ/RZ5Sm/NhbprkDRUMVzekpzrigYEC+XJaJSaVpSL5Qyif1mZLZW+AWNIoEM0LZ7/UFe8KyS2+gcW5Q==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.6.1.tgz", + "integrity": "sha512-R6ziaQw0pgMMzLVVD7Q76Iq01HGuwSNnbUgTgrqTbmw031dTlh7rnlJd1jXM6gBjR6kPTuV98hqMhMyHjrLKIg==", "optional": true }, "@node-rs/bcrypt-linux-x64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.4.1.tgz", - "integrity": "sha512-CvG1gBTAg0Vv9MUbESH/3g2k+oak+NB3jVv4vreTsQu8jI7AVk4PSCMygiV+oWaoNA4Yhu6H+M+M6JccvtaYtg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.6.1.tgz", + "integrity": "sha512-GwOFrzHN+Em+OhViA9hCmr/VGTVVl9OcASgG6ehT1PM7CB6zuhONBuvCUCoRyP03zY5ZkHbv8ODqAj9a9WGV2A==", "optional": true }, "@node-rs/bcrypt-linux-x64-musl": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.4.1.tgz", - "integrity": "sha512-Q71g6aJ88VDz8ljIhFd8g3Uj+k+n7vhe6h1o/aO/Atqv2+YcRuZlrGohXvwf4Vu4RYNi99EkQu+uK46QjPJTmQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.6.1.tgz", + "integrity": "sha512-koksZzVpwwmLsJTzUa0RfDgFNzSaXsUUo4wDpgQsn9MON0epSxrkZAc3Lw2oGrDRIhgH/kv/9aZExJEFo1Mj9A==", "optional": true }, "@node-rs/bcrypt-win32-ia32-msvc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.4.1.tgz", - "integrity": "sha512-A8S9557mVubI6o6dlYPZwdOKQBmA2sEzzwFIIxx257Mv5Zwt44x7hXwy9DBc98NaIyVBrC9eG5zxpAu/12r2lQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.6.1.tgz", + "integrity": "sha512-rp2kChdJf0dqYoynZzY8MjcSWrdZ3/B3EszZMlEjDfj40EXF7TOYNIavk58qPm4m70II1l46bi51FStEjvA3bw==", "optional": true }, "@node-rs/bcrypt-win32-x64-msvc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.4.1.tgz", - "integrity": "sha512-24xUag1/BwuBviRpozXnYQKGsqfriQw3VaCBQb6chvUTwQVjrndYmZfW+TMrCWLgnD1qRT3T0u3cZoOY9QxknA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.6.1.tgz", + "integrity": "sha512-6ykZKa9ydU9CFx2hbR1wuzpngx63MPK7mJMZgbetyOPpGEyixHDz/mSvpywptCGUEuuDbOE4rbc3Afw6dEf4TA==", "optional": true }, "@node-rs/helper": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-1.2.1.tgz", - "integrity": "sha512-R5wEmm8nbuQU0YGGmYVjEc0OHtYsuXdpRG+Ut/3wZ9XAvQWyThN08bTh2cBJgoZxHQUPtvRfeQuxcAgLuiBISg==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-1.3.3.tgz", + "integrity": "sha512-p4OdfQObGN9YFy5WZaGwlPYICQSe7xZYyXB0sxREmvj1HzGKp5bPg2PlfgfMZEfnjIA882B9ZrnagYzZihIwjA==", "optional": true, "requires": { - "@napi-rs/triples": "^1.0.3" + "@napi-rs/triples": "^1.1.0" } }, "@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, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1525,14 +22098,12 @@ "@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 + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, "@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, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1548,14 +22119,14 @@ } }, "@octokit/core": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", - "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.0", + "@octokit/request": "^5.6.3", "@octokit/request-error": "^2.0.5", "@octokit/types": "^6.0.3", "before-after-hook": "^2.2.0", @@ -1571,14 +22142,6 @@ "@octokit/types": "^6.0.3", "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } } }, "@octokit/graphql": { @@ -1593,56 +22156,51 @@ } }, "@octokit/openapi-types": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", - "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==", + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", - "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", + "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", "dev": true, "requires": { - "@octokit/types": "^6.34.0" + "@octokit/types": "^6.40.0" } }, "@octokit/plugin-request-log": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true + "dev": true, + "requires": {} }, "@octokit/plugin-rest-endpoint-methods": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", - "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", + "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", "dev": true, "requires": { - "@octokit/types": "^6.34.0", + "@octokit/types": "^6.39.0", "deprecation": "^2.3.1" } }, "@octokit/request": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz", - "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", "@octokit/request-error": "^2.1.0", "@octokit/types": "^6.16.1", "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.7", "universal-user-agent": "^6.0.0" }, "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -1651,6 +22209,28 @@ "requires": { "whatwg-url": "^5.0.0" } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } } } }, @@ -1678,38 +22258,27 @@ } }, "@octokit/types": { - "version": "6.34.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", - "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", "dev": true, "requires": { - "@octokit/openapi-types": "^11.2.0" + "@octokit/openapi-types": "^12.11.0" } }, - "@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==" - }, "@parse/fs-files-adapter": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@parse/fs-files-adapter/-/fs-files-adapter-1.2.2.tgz", - "integrity": "sha512-VUsVZXgt53FULqUd9xqGDW6RXes62qHXTNOeRSlS1MOemiCdtQOUGgLHgjdYQXnZ1hPLkxZKph96AluZUb953g==" - }, - "@parse/minami": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@parse/minami/-/minami-1.0.0.tgz", - "integrity": "sha512-Rw+p0WdOOypFPVJsmhyiI+Q056ZxdP2iAtObnU1DZrsvKZTf5x0B/0SjIt0hUgWp+COjqi/p17VdBU9IAD/NJg==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@parse/fs-files-adapter/-/fs-files-adapter-2.0.1.tgz", + "integrity": "sha512-9DY0T9lK73Ysw+wxxsBt9rpxWxJpMlHl/fTW175XSajusW0ZP5jERI3BTKeclV28eVmSU690EO2vnwCURsPZ7g==" }, "@parse/node-apn": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@parse/node-apn/-/node-apn-5.1.3.tgz", - "integrity": "sha512-Bwhmbm895lEIF2772PJ8dSvBjrtOG9/q/TDMxmX40IgZxQFoXS73+JUIKTq3CA7SUB/Szu5roJINQ0L2U/1MJw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@parse/node-apn/-/node-apn-6.0.1.tgz", + "integrity": "sha512-QQxqEN/zbtEkSgj41oX/tQUavML+G+JHeQi2YVlgZlponnwIxA3fb5tEbXPm+fdR6rL1pi2/z2PcOwINOyx2eA==", "requires": { "debug": "4.3.3", - "jsonwebtoken": "8.5.1", - "node-forge": "1.3.0", + "jsonwebtoken": "9.0.0", + "node-forge": "1.3.1", "verror": "1.10.1" }, "dependencies": { @@ -1720,21 +22289,6 @@ "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==" - }, - "verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } } } }, @@ -1746,58 +22300,150 @@ "debug": "^3.1.0", "lodash": "^4.17.10", "request": "2.88.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } } }, "@parse/push-adapter": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@parse/push-adapter/-/push-adapter-4.1.2.tgz", - "integrity": "sha512-034vZTlAzgdfefIY4+Q4j8DHS/VwUAIVoh1JeRkHNfyQmUQ++uKbQbUQdJ/nf11HHS69kwLENs13BmhlHMpyHQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@parse/push-adapter/-/push-adapter-5.1.1.tgz", + "integrity": "sha512-gazpr/H8tnEhQtDPPYctsvNU0ICkkZAB0wIOnt5AOFANZ9rldl9vRX/BONtmrpewNinfCnqkGUvI9+tVO+rw4w==", "requires": { - "@parse/node-apn": "5.1.3", + "@parse/node-apn": "6.0.1", "@parse/node-gcm": "1.0.2", - "npmlog": "4.1.2", - "parse": "3.4.0" + "firebase-admin": "12.0.0", + "npmlog": "7.0.1", + "parse": "4.2.0" }, "dependencies": { - "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "parse": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/parse/-/parse-3.4.0.tgz", - "integrity": "sha512-FMZLxPW6PvrBgxkXc9AmnYsFKvPwiS4G2n9OI4mdfiSoNzIVLc+bXzlUdJ+I7hiqHsBTP0BrdQczw2/cnVkJ6w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/parse/-/parse-4.2.0.tgz", + "integrity": "sha512-K8bWs0wM2qRhkSr6N16j8OvsF6Uallrynqng9e+tzR3RdKuB09vaJh48qrf9MbiJ1Ya4JZI7AfEHYF+ywEKs7Q==", "requires": { - "@babel/runtime": "7.15.4", - "@babel/runtime-corejs3": "7.14.7", + "@babel/runtime-corejs3": "7.21.0", "crypto-js": "4.1.1", - "idb-keyval": "5.0.6", + "idb-keyval": "6.2.0", "react-native-crypto-js": "1.0.0", - "uuid": "3.4.0", - "ws": "7.5.1", + "uuid": "9.0.0", + "ws": "8.13.0", "xmlhttprequest": "1.8.0" } }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "ws": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.1.tgz", - "integrity": "sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==" + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "requires": {} } } }, - "@repeaterjs/repeater": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", - "integrity": "sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==" + "@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==" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "@redis/bloom": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "requires": {} + }, + "@redis/client": { + "version": "1.5.14", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz", + "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==", + "requires": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", + "yallist": "4.0.0" + } + }, + "@redis/graph": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "requires": {} + }, + "@redis/json": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", + "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "requires": {} + }, + "@redis/search": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", + "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", + "requires": {} + }, + "@redis/time-series": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", + "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "requires": {} }, "@saithodev/semantic-release-backmerge": { "version": "2.1.2", @@ -1811,52 +22457,6 @@ "execa": "^5.1.1", "lodash": "^4.17.21", "semantic-release": ">=13.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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" - } - }, - "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 - }, - "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 - }, - "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 - } } }, "@samverschueren/stream-to-observable": { @@ -1880,32 +22480,10 @@ "lodash": "^4.17.4" }, "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", "dev": true } } @@ -1923,72 +22501,12 @@ "import-from": "^3.0.0", "lodash": "^4.17.4", "micromatch": "^4.0.2" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "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 - }, - "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==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } } }, "@semantic-release/error": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", - "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", "dev": true }, "@semantic-release/git": { @@ -2007,63 +22525,43 @@ "p-reduce": "^2.0.0" }, "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true }, - "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==", + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { - "to-regex-range": "^5.0.1" + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" } }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "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, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "pump": "^3.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==", + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true - }, - "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==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -2091,19 +22589,16 @@ "url-join": "^4.0.0" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true }, "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -2111,33 +22606,11 @@ "universalify": "^2.0.0" } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "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 - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true } } }, @@ -2162,61 +22635,22 @@ "tempy": "^1.0.0" }, "dependencies": { - "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" - } + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true }, "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } - }, - "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 - }, - "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 - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true } } }, @@ -2236,44 +22670,21 @@ "into-stream": "^6.0.0", "lodash": "^4.17.4", "read-pkg-up": "^7.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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 - }, - "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 - } } }, "@sindresorhus/is": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", - "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", "dev": true }, "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, "requires": { - "defer-to-connect": "^2.0.0" + "defer-to-connect": "^2.0.1" } }, "@tootallnate/once": { @@ -2283,53 +22694,56 @@ "dev": true }, "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "requires": { "@types/connect": "*", "@types/node": "*" } }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, + "@types/busboy": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.3.tgz", + "integrity": "sha512-YMBLFN/xBD8bnqywIlGyYqsNFXu6bsiY7h3Ae0kO17qEuTjsqeyYMRPSUDacIKIquws2Y6KjmxAyNx8xB3xQbw==", "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" + "@types/node": "*" } }, + "@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "optional": true + }, "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "requires": { "@types/node": "*" } }, "@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.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "requires": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "@types/express-serve-static-core": { - "version": "4.17.29", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", - "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", "requires": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "@types/http-cache-semantics": { @@ -2338,52 +22752,56 @@ "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", "dev": true }, - "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "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/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "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": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", "requires": { "@types/node": "*" } }, - "@types/keyv": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", - "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "@types/linkify-it": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "dev": true + }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", "dev": true, "requires": { - "@types/node": "*" + "@types/linkify-it": "*", + "@types/mdurl": "*" } }, + "@types/mdurl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "dev": true + }, "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "@types/minimist": { "version": "1.2.2", @@ -2392,9 +22810,21 @@ "dev": true }, "@types/node": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz", - "integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==" + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "requires": { + "@types/node": "*", + "form-data": "4.0.0" + } }, "@types/normalize-package-data": { "version": "2.4.1", @@ -2402,6 +22832,11 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "@types/object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@types/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==" + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -2409,39 +22844,71 @@ "dev": true }, "@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==" + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" }, "@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==" - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "optional": true, "requires": { - "@types/node": "*" + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + }, + "dependencies": { + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } } }, "@types/retry": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", - "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "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==", + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "requires": { "@types/mime": "^1", "@types/node": "*" } }, + "@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "optional": true + }, "@types/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -2456,160 +22923,86 @@ "@types/webidl-conversions": "*" } }, - "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@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/types": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.0.tgz", - "integrity": "sha512-9XR5q9mk7DCXgXLS7REIVs+BaAswfdHhx91XqlJklmqWpTALGjygWVIb/UnLh4NWhfwhR5wNe1yTyCInxVhLqQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.0.tgz", - "integrity": "sha512-QHl2014t3ptg+xpmOSSPn5hm4mY8D4s97ftzyk9BZ8RxYQ3j73XcwuijnJ9cMa6DO4aLXeo8XS3z1omT9LA/Eg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/visitor-keys": "4.31.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.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.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.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 - }, - "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" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.0.tgz", - "integrity": "sha512-HUcRp2a9I+P21+O21yu3ezv3GEPGjyGiXoEUQwZXjR8UxRApGeLyWH4ZIIUSalE28aG4YsV6GjtaAVB3QKOu0w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.31.0", - "eslint-visitor-keys": "^2.0.0" + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" }, "dependencies": { "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.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true } } }, - "@wry/context": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.6.1.tgz", - "integrity": "sha512-LOmVnY1iTU2D8tv4Xf6MVMZZ+juIJ87Kt/plMijjN20NMAXGmH4u8bS1t0uT74cZ5gwpocYueV58YwyI8y+GKw==", + "@wry/caches": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz", + "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==", "dev": true, "requires": { "tslib": "^2.3.0" - }, - "dependencies": { - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - } } }, - "@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==", + "@wry/context": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz", + "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==", "dev": true, "requires": { - "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 - } + "tslib": "^2.3.0" } }, - "@wry/trie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.3.1.tgz", - "integrity": "sha512-WwB53ikYudh9pIorgxrkHKrQZcCqNM/Q/bDzZBffEaGUKGuHrRb3zZUT9Sh2qw9yogC7SsdRmQ1ER0pqvd3bfw==", + "@wry/equality": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz", + "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==", "dev": true, "requires": { "tslib": "^2.3.0" - }, - "dependencies": { - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - } } }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "@wry/trie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz", + "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==", "dev": true, "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "tslib": "^2.3.0" } }, "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, "requires": { "event-target-shim": "^5.0.0" } @@ -2626,59 +23019,26 @@ "requires": { "mime-types": "~2.1.34", "negotiator": "0.6.3" - }, - "dependencies": { - "mime-db": { - "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.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.52.0" - } - } } }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "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", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "requires": {} }, "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==", - "dev": true, + "devOptional": true, "requires": { "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 - } } }, "aggregate-error": { @@ -2691,76 +23051,67 @@ "indent-string": "^4.0.0" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "all-node-versions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-8.0.0.tgz", - "integrity": "sha512-cF8ibgj23U7ai4qjSFzpeccwDXUlPFMzKe0Z6qf6gChR+9S0JMyzYz6oYz4n0nHi/FLH9BJIefsONsMH/WDM2w==", - "dev": true, - "requires": { - "fetch-node-website": "^5.0.3", - "filter-obj": "^2.0.1", - "get-stream": "^5.1.0", - "global-cache-dir": "^2.0.0", - "jest-validate": "^25.3.0", - "path-exists": "^4.0.0", - "semver": "^7.3.2", - "write-file-atomic": "^3.0.3" - } - }, - "ampersand-events": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ampersand-events/-/ampersand-events-2.0.2.tgz", - "integrity": "sha1-9AK8LhgwX6vZldvc07cFe73X00c=", - "dev": true, - "requires": { - "ampersand-version": "^1.0.2", - "lodash": "^4.6.1" - } - }, - "ampersand-state": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/ampersand-state/-/ampersand-state-5.0.3.tgz", - "integrity": "sha512-sr904K5zvw6mkGjFHhTcfBIdpoJ6mn/HrFg7OleRmBpw3apLb3Z0gVrgRTb7kK1wOLI34vs4S+IXqNHUeqWCzw==", - "dev": true, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "requires": { - "ampersand-events": "^2.0.1", - "ampersand-version": "^1.0.0", - "array-next": "~0.0.1", - "key-tree-store": "^1.3.0", - "lodash": "^4.12.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "ampersand-version": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ampersand-version/-/ampersand-version-1.0.2.tgz", - "integrity": "sha1-/489TOrE0yzNg/a9Zpc5f3tZ4sA=", + "all-node-versions": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-11.3.0.tgz", + "integrity": "sha512-psMkc5s3qpr+QMfires9bC4azRYciPWql1wqZKMsYRh1731qefQDH2X4+O19xSBX6u0Ra/8Y5diG6y/fEmqKsw==", "dev": true, "requires": { - "find-root": "^0.1.1", - "through2": "^0.6.3" + "fetch-node-website": "^7.3.0", + "filter-obj": "^5.1.0", + "get-stream": "^6.0.0", + "global-cache-dir": "^4.3.1", + "is-plain-obj": "^4.1.0", + "path-exists": "^5.0.0", + "semver": "^7.3.7", + "write-file-atomic": "^4.0.1" + }, + "dependencies": { + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } } }, "ansi": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", "dev": true }, "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==", "dev": true }, "ansi-escapes": { @@ -2781,15 +23132,14 @@ } }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "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" } @@ -2797,7 +23147,7 @@ "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 }, "any-observable": { @@ -2806,62 +23156,36 @@ "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", "dev": true }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "optional": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "apollo-upload-client": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-16.0.0.tgz", - "integrity": "sha512-aLhYucyA0T8aBEQ5g+p13qnR9RUyL8xqb8FSZ7e/Kw2KUOsotLUlFluLobqaE7JSUFwc6sKfXIcwB7y4yEjbZg==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-17.0.0.tgz", + "integrity": "sha512-pue33bWVbdlXAGFPkgz53TTmxVMrKeQr0mdRcftNY+PoHIdbGZD0hoaXHvO6OePJAkFz7OiCFUf98p1G/9+Ykw==", "dev": true, "requires": { "extract-files": "^11.0.0" } }, - "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==", - "dev": true, - "requires": { - "@wry/equality": "^0.1.2", - "fast-json-stable-stringify": "^2.0.0", - "ts-invariant": "^0.4.0", - "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 - } - } - }, "app-module-path": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", - "integrity": "sha1-ZBqlXft9am8KgUHEucCqULbCTdU=", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", "dev": true }, "append-transform": { @@ -2874,61 +23198,37 @@ } }, "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" } }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "argv-formatter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", - "integrity": "sha1-oMoMvCmltz6Dbuvhy/bF4OTrgvk=", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", "dev": true }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "optional": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "optional": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "optional": true - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -2937,13 +23237,7 @@ "array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", - "dev": true - }, - "array-next": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/array-next/-/array-next-0.0.1.tgz", - "integrity": "sha1-5eRmCkwn/agVH/d2QnXQCQAGK+E=", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "dev": true }, "array-union": { @@ -2952,54 +23246,40 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "optional": true - }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true }, "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "requires": { "safer-buffer": "~2.1.0" } }, "assert-options": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.7.0.tgz", - "integrity": "sha512-7q9uNH/Dh8gFgpIIb9ja8PJEWA5AQy3xnBC8jtKs8K/gNVCr1K6kIvlm59HUyYgvM7oEDoLzGgPcGd9FqhtXEQ==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.1.tgz", + "integrity": "sha512-5lNGRB5g5i2bGIzb+J1QQE1iKU/WEMVBReFIc5pPDWjcPj23otPL0eI6PB2v7QPi0qU6Mhym5D3y0ZiSIOf3GA==" }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "optional": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" }, "ast-module-types": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-2.7.1.tgz", - "integrity": "sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-4.0.0.tgz", + "integrity": "sha512-Kd0o8r6CDazJGCRzs8Ivpn0xj19oNKrULhoJFzhGjRsLpekF2zyZs9Ukz+JvZhWD6smszfepakTFhAaYpsI12g==", "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async": { @@ -3007,17 +23287,18 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true, - "optional": true + "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==", + "requires": { + "retry": "0.13.1" + } }, "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==" }, "at-least-node": { "version": "1.0.0", @@ -3025,50 +23306,58 @@ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "optional": 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", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "babel-plugin-polyfill-corejs2": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", + "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.5.0", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } } }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", "dev": true, "requires": { - "object.assign": "^4.1.0" + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.5.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==" }, "backoff": { "version": "2.5.0", @@ -3081,91 +23370,18 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "optional": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } - } + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-nodejs": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz", - "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs=", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "devOptional": true }, "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" } @@ -3173,39 +23389,49 @@ "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==" }, "before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, + "bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", "optional": true }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } + "optional": true }, "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==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, "bluebird": { @@ -3215,12 +23441,12 @@ "dev": true }, "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==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "requires": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -3228,7 +23454,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -3241,20 +23467,17 @@ "ms": "2.0.0" } }, - "qs": { - "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" - } + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true }, "bottleneck": { @@ -3267,73 +23490,41 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "optional": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } + "fill-range": "^7.0.1" } }, "browserslist": { - "version": "4.16.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", - "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", - "dev": true, + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "requires": { - "caniuse-lite": "^1.0.30001251", - "colorette": "^1.3.0", - "electron-to-chromium": "^1.3.811", - "escalade": "^3.1.1", - "node-releases": "^1.1.75" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" } }, "bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", - "dev": true + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz", + "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==" }, "buffer": { "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" @@ -3358,18 +23549,18 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, "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-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", "dev": true }, "buffer-writer": { @@ -3390,56 +23581,33 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "optional": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } - } - }, "cacheable-lookup": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", - "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", - "dev": true, - "requires": { - "@types/keyv": "^3.1.1", - "keyv": "^4.0.0" - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true }, "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "version": "10.2.7", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.7.tgz", + "integrity": "sha512-I4SA6mKgDxcxVbSt/UmIkb9Ny8qSkg6ReBHtAAXnZHk7KOSx5g3DTiAOaYzcHCs6oOdHn+bip9T48E6tMvK9hw==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.2", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "dependencies": { + "normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "dev": true + } } }, "cachedir": { @@ -3489,8 +23657,17 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } }, "camelcase": { "version": "5.3.1", @@ -3510,15 +23687,14 @@ } }, "caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", - "dev": true + "version": "1.0.30001594", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz", + "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==" }, "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", @@ -3528,50 +23704,31 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, "catharsis": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", - "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "caw": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", - "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, "requires": { - "get-proxy": "^2.0.0", - "isurl": "^1.0.0-alpha5", - "tunnel-agent": "^0.6.0", - "url-to-options": "^1.0.1" + "lodash": "^4.17.15" } }, "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" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "cheerio": { "version": "0.22.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", - "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", "dev": true, "requires": { "css-select": "~1.2.0", @@ -3593,61 +23750,70 @@ } }, "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "optional": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.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" } }, - "ci-info": { + "chownr": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", "dev": true, - "optional": true, "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "source-map": "~0.6.0" }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "clean-jsdoc-theme": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/clean-jsdoc-theme/-/clean-jsdoc-theme-4.2.7.tgz", + "integrity": "sha512-yLLxwTFw7N9/toUCcFmKkwJmv4LO2pQWYNETcU3Vv+n2al2L2ohb7xWoXLjp5m3OljC9b1m+o4adzY0YH6Ep4A==", + "dev": true, + "requires": { + "@jsdoc/salty": "^0.2.4", + "fs-extra": "^10.1.0", + "html-minifier": "^4.0.0", + "klaw-sync": "^6.0.0", + "lodash": "^4.17.21", + "nanoid": "^3.3.4", + "showdown": "^2.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "optional": true, "requires": { - "is-descriptor": "^0.1.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true } } }, @@ -3657,35 +23823,6 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, - "cli-color": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", - "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.61", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" - }, - "dependencies": { - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - } - } - }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -3696,98 +23833,28 @@ } }, "cli-progress": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.9.0.tgz", - "integrity": "sha512-g7rLWfhAo/7pF+a/STFH/xPyosaL1zgADhI0OM83hl3c7S43iGvJWEAV2QuDOnQ8i6EMBj/u4+NTd0d5L+4JfA==", + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.11.2.tgz", + "integrity": "sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==", "dev": true, "requires": { - "colors": "^1.1.2", - "string-width": "^4.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } + "string-width": "^4.2.3" } }, "cli-spinners": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", - "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "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.0", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", - "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", + "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": "^1.1.2", - "object-assign": "^4.1.0", + "@colors/colors": "1.5.0", "string-width": "^4.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "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==", - "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==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } } }, "cli-truncate": { @@ -3798,259 +23865,30 @@ "requires": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "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 - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "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==", - "dev": true - }, - "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==", - "dev": true - }, - "slice-ansi": { - "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", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.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==", - "dev": true - }, "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" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "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" - }, - "dependencies": { - "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 - } - } - }, - "clui": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/clui/-/clui-0.3.6.tgz", - "integrity": "sha512-Z4UbgZILlIAjkEkZiDOa2aoYjohKx7fa6DxIh6cE9A6WNWZ61iXfQc6CmdC9SKdS5nO0P0UyQ+WfoXfB65e3HQ==", - "dev": true, - "requires": { - "cli-color": "0.3.2" - }, - "dependencies": { - "cli-color": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-0.3.2.tgz", - "integrity": "sha1-dfpfcowwjMSsWUsF4GzF2A2szYY=", - "dev": true, - "requires": { - "d": "~0.1.1", - "es5-ext": "~0.10.2", - "memoizee": "0.3.x", - "timers-ext": "0.1.x" - } - }, - "d": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", - "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "es6-iterator": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", - "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", - "dev": true, - "requires": { - "d": "~0.1.1", - "es5-ext": "~0.10.5", - "es6-symbol": "~2.0.1" - } - }, - "es6-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", - "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", - "dev": true, - "requires": { - "d": "~0.1.1", - "es5-ext": "~0.10.5" - } - }, - "es6-weak-map": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", - "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", - "dev": true, - "requires": { - "d": "~0.1.1", - "es5-ext": "~0.10.6", - "es6-iterator": "~0.1.3", - "es6-symbol": "~2.0.1" - } - }, - "memoizee": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.3.10.tgz", - "integrity": "sha1-TsoNiu057J0Bf0xcLy9kMvQuXI8=", - "dev": true, - "requires": { - "d": "~0.1.1", - "es5-ext": "~0.10.11", - "es6-weak-map": "~0.1.4", - "event-emitter": "~0.3.4", - "lru-queue": "0.1", - "next-tick": "~0.2.2", - "timers-ext": "0.1" - } - }, - "next-tick": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz", - "integrity": "sha1-ddpKkn7liH45BliABltzNkE7MQ0=", - "dev": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "optional": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true + }, + "cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==" + }, "color": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", @@ -4071,7 +23909,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "color-string": { "version": "1.9.1", @@ -4082,11 +23920,10 @@ "simple-swizzle": "^0.2.2" } }, - "colorette": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", - "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", - "dev": true + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "colors": { "version": "1.4.0", @@ -4094,6 +23931,30 @@ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true }, + "colors-option": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/colors-option/-/colors-option-4.5.0.tgz", + "integrity": "sha512-Soe5lerRg3erMRgYC0EC696/8dMCGpBzcQchFfi55Yrkja8F+P7cUt0LVTIg7u5ob5BexLZ/F1kO+ejmv+nq8w==", + "dev": true, + "requires": { + "chalk": "^5.0.1", + "is-plain-obj": "^4.1.0" + }, + "dependencies": { + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true + }, + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true + } + } + }, "colorspace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", @@ -4112,14 +23973,14 @@ } }, "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==" }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "compare-func": { @@ -4132,67 +23993,37 @@ "dot-prop": "^5.1.0" } }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true, - "optional": true + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "connected-domain": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/connected-domain/-/connected-domain-1.0.0.tgz", - "integrity": "sha1-v+dyOMdL5FOnnwy2BY3utPI1jpM=", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "requires": { - "safe-buffer": "5.1.2" - }, - "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 - } + "safe-buffer": "5.2.1" } }, "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==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, "conventional-changelog-angular": { "version": "5.0.13", @@ -4222,31 +24053,11 @@ "through2": "^4.0.0" }, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - } } } }, @@ -4261,57 +24072,24 @@ } }, "conventional-commits-parser": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz", - "integrity": "sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", "dev": true, "requires": { - "JSONStream": "^1.0.4", "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - } - } } }, "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.5.0", @@ -4323,40 +24101,25 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "optional": true - }, "core-js-compat": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.16.2.tgz", - "integrity": "sha512-4lUshXtBXsdmp8cDWh6KKiHUg40AjiuPD3bOWkNVsr1xkAhpUqCjaZ8lB1bKx9Gb5fXcbRbFJ4f4qpRIRTuJqQ==", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", "dev": true, "requires": { - "browserslist": "^4.16.7", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } + "browserslist": "^4.22.3" } }, "core-js-pure": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.16.2.tgz", - "integrity": "sha512-oxKe64UH049mJqrKkynWp6Vu0Rlm/BTXO/bJZuN2mmR3RtOFNepLlSWDd1eo16PzHpQAoNG97rLU1V/YxesJjw==" + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.0.tgz", + "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==" }, "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=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, "cors": { "version": "2.8.5", @@ -4368,16 +24131,16 @@ } }, "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", + "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", - "yaml": "^1.7.2" + "yaml": "^1.10.0" } }, "cross-env": { @@ -4389,41 +24152,24 @@ "cross-spawn": "^7.0.1" } }, + "cross-inspect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.0.tgz", + "integrity": "sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==", + "requires": { + "tslib": "^2.4.0" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, - "cross-undici-fetch": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/cross-undici-fetch/-/cross-undici-fetch-0.4.3.tgz", - "integrity": "sha512-mv1jusEQsFnBHEBkpFaYROKAzAWyuW8ZyN48NcyqkjLGRrscMKuFRmUigUrkE/pdprQZjNTQQ/aWJKe6F4tzTA==", - "requires": { - "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.1.0", - "web-streams-polyfill": "^3.2.0" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, "crypto-js": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", @@ -4439,7 +24185,7 @@ "css-select": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", "dev": true, "requires": { "boolbase": "~1.0.0", @@ -4461,12 +24207,19 @@ "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" + }, + "dependencies": { + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + } } }, "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" } @@ -4484,23 +24237,23 @@ "dev": true }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "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" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "requires": { "decamelize": "^1.1.0", @@ -4510,27 +24263,11 @@ "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true } } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "optional": true - }, - "decomment": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.4.tgz", - "integrity": "sha512-8eNlhyI5cSU4UbBlrtagWpR03dqXcE5IR9zpe7PnO6UzReXDskucsD8usgrzUmQ6qJ3N82aws/p/mu/jqbURWw==", - "dev": true, - "requires": { - "esprima": "4.0.1" - } - }, "decompress": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", @@ -4559,7 +24296,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true } } @@ -4567,18 +24304,26 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } }, "decompress-response": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", - "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, "requires": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + } } }, "decompress-tar": { @@ -4595,7 +24340,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true } } @@ -4622,7 +24367,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true } } @@ -4641,7 +24386,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true } } @@ -4649,7 +24394,7 @@ "decompress-unzip": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", "dev": true, "requires": { "file-type": "^3.8.0", @@ -4661,13 +24406,13 @@ "file-type": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", "dev": true }, "get-stream": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", "dev": true, "requires": { "object-assign": "^4.0.1", @@ -4677,7 +24422,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -4685,7 +24430,7 @@ "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, "deep-diff": { @@ -4701,10 +24446,9 @@ "dev": true }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "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==" }, "deepcopy": { "version": "2.1.0", @@ -4715,18 +24459,18 @@ } }, "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", "dev": true, "requires": { "strip-bom": "^4.0.0" } }, "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" @@ -4738,71 +24482,10 @@ "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "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==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } - } - }, "del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", "dev": true, "requires": { "globby": "^11.0.1", @@ -4815,15 +24498,6 @@ "slash": "^3.0.0" }, "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -4835,17 +24509,13 @@ "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==" }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true }, "depd": { "version": "2.0.0", @@ -4853,16 +24523,16 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "dependency-tree": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-8.1.1.tgz", - "integrity": "sha512-bl5U16VQpaYxD0xvcnCH/dTctCiWnsVWymh9dNjbm4T00Hm21flu1VLnNueKCj7+3uusbcJhKKKtiWrpU0I+Nw==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-9.0.0.tgz", + "integrity": "sha512-osYHZJ1fBSon3lNLw70amAXsQ+RGzXsPvk9HbBgTLbp/bQBmpH5mOmsUvqXU+YEWVU0ZLewsmzOET/8jWswjDQ==", "dev": true, "requires": { "commander": "^2.20.3", "debug": "^4.3.1", - "filing-cabinet": "^3.0.0", - "precinct": "^8.0.0", - "typescript": "^3.9.7" + "filing-cabinet": "^3.0.1", + "precinct": "^9.0.0", + "typescript": "^4.0.0" }, "dependencies": { "commander": { @@ -4871,20 +24541,49 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "detective-stylus": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-3.0.0.tgz", + "integrity": "sha512-1xYTzbrduExqMYmte7Qk99IRA3Aa6oV7PYzd+3yDcQXkmENvyGF/arripri6lxRDdNYEb4fZFuHtNRAXbz3iAA==", + "dev": true + }, + "module-definition": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-4.1.0.tgz", + "integrity": "sha512-rHXi/DpMcD2qcKbPCTklDbX9lBKJrUSl971TW5l6nMpqKCIlzJqmQ8cfEF5M923h2OOLHPDVlh5pJxNyV+AJlw==", "dev": true, "requires": { - "ms": "2.1.2" + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1" } }, - "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 + "precinct": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-9.2.1.tgz", + "integrity": "sha512-uzKHaTyiVejWW7VJtHInb9KBUq9yl9ojxXGujhjhDmPon2wgZPBKQIKR+6csGqSlUeGXAA4MEFnU6DesxZib+A==", + "dev": true, + "requires": { + "@dependents/detective-less": "^3.0.1", + "commander": "^9.5.0", + "detective-amd": "^4.1.0", + "detective-cjs": "^4.1.0", + "detective-es6": "^3.0.1", + "detective-postcss": "^6.1.1", + "detective-sass": "^4.1.1", + "detective-scss": "^3.0.1", + "detective-stylus": "^3.0.0", + "detective-typescript": "^9.1.1", + "module-definition": "^4.1.0", + "node-source-walk": "^5.0.1" + }, + "dependencies": { + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true + } + } } } }, @@ -4900,34 +24599,34 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "detective-amd": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-3.1.0.tgz", - "integrity": "sha512-G7wGWT6f0VErjUkE2utCm7IUshT7nBh7aBBH2VBOiY9Dqy2DMens5iiOvYCuhstoIxRKLrnOvVAz4/EyPIAjnw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-4.2.0.tgz", + "integrity": "sha512-RbuEJHz78A8nW7CklkqTzd8lDCN42En53dgEIsya0DilpkwslamSZDasLg8dJyxbw46OxhSQeY+C2btdSkCvQQ==", "dev": true, "requires": { - "ast-module-types": "^2.7.0", + "ast-module-types": "^4.0.0", "escodegen": "^2.0.0", - "get-amd-module-type": "^3.0.0", - "node-source-walk": "^4.0.0" + "get-amd-module-type": "^4.1.0", + "node-source-walk": "^5.0.1" } }, "detective-cjs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-3.1.1.tgz", - "integrity": "sha512-JQtNTBgFY6h8uT6pgph5QpV3IyxDv+z3qPk/FZRDT9TlFfm5dnRtpH39WtQEr1khqsUxVqXzKjZHpdoQvQbllg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-4.1.0.tgz", + "integrity": "sha512-QxzMwt5MfPLwS7mG30zvnmOvHLx5vyVvjsAV6gQOyuMoBR5G1DhS1eJZ4P10AlH+HSnk93mTcrg3l39+24XCtg==", "dev": true, "requires": { - "ast-module-types": "^2.4.0", - "node-source-walk": "^4.0.0" + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1" } }, "detective-es6": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.0.tgz", - "integrity": "sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-3.0.1.tgz", + "integrity": "sha512-evPeYIEdK1jK3Oji5p0hX4sPV/1vK+o4ihcWZkMQE6voypSW/cIBiynOLxQk5KOOQbdP8oOAsYqouMTYO5l1sw==", "dev": true, "requires": { - "node-source-walk": "^4.0.0" + "node-source-walk": "^5.0.0" } }, "detective-less": { @@ -4941,141 +24640,64 @@ "node-source-walk": "^4.0.0" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "node-source-walk": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.3.0.tgz", + "integrity": "sha512-8Q1hXew6ETzqKRAs3jjLioSxNfT1cx74ooiF8RlAONwVMcfq+UdzLC2eB5qcPldUxaE5w3ytLkrmV1TGddhZTA==", "dev": true, "requires": { - "ms": "2.1.2" + "@babel/parser": "^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 } } }, "detective-postcss": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-5.0.0.tgz", - "integrity": "sha512-IBmim4GTEmZJDBOAoNFBskzNryTmYpBq+CQGghKnSGkoGWascE8iEo98yA+ZM4N5slwGjCr/NxCm+Kzg+q3tZg==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-6.1.3.tgz", + "integrity": "sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw==", "dev": true, "requires": { - "debug": "^4.3.1", "is-url": "^1.2.4", - "postcss": "^8.2.13", - "postcss-values-parser": "^5.0.0" - }, - "dependencies": { - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 - }, - "postcss-values-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-5.0.0.tgz", - "integrity": "sha512-2viDDjMMrt21W2izbeiJxl3kFuD/+asgB0CBwPEgSyhCmBnDIa/y+pLaoyX+q3I3DHH0oPPL3cgjVTQvlS1Maw==", - "dev": true, - "requires": { - "color-name": "^1.1.4", - "is-url-superb": "^4.0.0", - "quote-unquote": "^1.0.0" - } - } + "postcss": "^8.4.23", + "postcss-values-parser": "^6.0.2" } }, "detective-sass": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-3.0.1.tgz", - "integrity": "sha512-oSbrBozRjJ+QFF4WJFbjPQKeakoaY1GiR380NPqwdbWYd5wfl5cLWv0l6LsJVqrgWfFN1bjFqSeo32Nxza8Lbw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-4.1.3.tgz", + "integrity": "sha512-xGRbwGaGte57gvEqM8B9GDiURY3El/H49vA6g9wFkxq9zalmTlTAuqWu+BsH0iwonGPruLt55tZZDEZqPc6lag==", "dev": true, "requires": { - "debug": "^4.1.1", - "gonzales-pe": "^4.2.3", - "node-source-walk": "^4.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 - } + "gonzales-pe": "^4.3.0", + "node-source-walk": "^5.0.1" } }, "detective-scss": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-2.0.1.tgz", - "integrity": "sha512-VveyXW4WQE04s05KlJ8K0bG34jtHQVgTc9InspqoQxvnelj/rdgSAy7i2DXAazyQNFKlWSWbS+Ro2DWKFOKTPQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-3.1.1.tgz", + "integrity": "sha512-FWkfru1jZBhUeuBsOeGKXKAVDrzYFSQFK2o2tuG/nCCFQ0U/EcXC157MNAcR5mmj+mCeneZzlkBOFJTesDjrww==", "dev": true, "requires": { - "debug": "^4.1.1", - "gonzales-pe": "^4.2.3", - "node-source-walk": "^4.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 - } + "gonzales-pe": "^4.3.0", + "node-source-walk": "^5.0.1" } }, "detective-stylus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-1.0.0.tgz", - "integrity": "sha1-UK7n24uruZA4HwEMY/q7pbWOVM0=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-2.0.1.tgz", + "integrity": "sha512-/Tvs1pWLg8eYwwV6kZQY5IslGaYqc/GACxjcaGudiNtN5nKCH6o2WnJK3j0gA3huCnoQcbv8X7oz/c1lnvE3zQ==", "dev": true }, "detective-typescript": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-7.0.0.tgz", - "integrity": "sha512-y/Ev98AleGvl43YKTNcA2Q+lyFmsmCfTTNWy4cjEJxoLkbobcXtRS0Kvx06daCgr2GdtlwLfNzL553BkktfJoA==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-9.1.1.tgz", + "integrity": "sha512-Uc1yVutTF0RRm1YJ3g//i1Cn2vx1kwHj15cnzQP6ff5koNzQ0idc1zAC73ryaWEulA0ElRXFTq6wOqe8vUQ3MA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "^4.8.2", - "ast-module-types": "^2.7.1", - "node-source-walk": "^4.2.0", - "typescript": "^3.9.7" + "@typescript-eslint/typescript-estree": "^5.55.0", + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1", + "typescript": "^4.9.5" } }, "dir-glob": { @@ -5087,17 +24709,10 @@ "path-type": "^4.0.0" } }, - "docopt": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/docopt/-/docopt-0.6.2.tgz", - "integrity": "sha1-so6eIiDaXsSffqW7JKR3h0Be6xE=", - "dev": true - }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "requires": { "esutils": "^2.0.2" } @@ -5130,7 +24745,7 @@ "domutils": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", "dev": true, "requires": { "dom-serializer": "0", @@ -5144,20 +24759,12 @@ "dev": true, "requires": { "is-obj": "^2.0.0" - }, - "dependencies": { - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - } } }, "downcache": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/downcache/-/downcache-0.0.9.tgz", - "integrity": "sha1-eQuwQkaJE2EVzpPyqhWUbG2AbQ4=", + "integrity": "sha512-AssoVsNYu5DnPY0Ro67lkbiAr66sk5IHuiIGm3pzFzWmTzkcEoFjDlG8szzP4x+ZN2OHehKTZbwDrC7l2Q52+g==", "dev": true, "requires": { "extend": "^3.0.0", @@ -5172,7 +24779,7 @@ "gauge": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", + "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", "dev": true, "requires": { "ansi": "^0.3.0", @@ -5185,155 +24792,68 @@ "npmlog": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", - "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", + "integrity": "sha512-DaL6RTb8Qh4tMe2ttPT1qWccETy2Vi5/8p+htMpLBeXJTr2CAqnF5WQtSP2eFpvaNbhLZ5uilDb98mRm4Q+lZQ==", "dev": true, "requires": { "ansi": "~0.3.1", "are-we-there-yet": "~1.1.2", "gauge": "~1.2.5" } - } - } - }, - "download": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", - "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", - "dev": true, - "requires": { - "caw": "^2.0.0", - "content-disposition": "^0.5.2", - "decompress": "^4.0.0", - "ext-name": "^5.0.0", - "file-type": "5.2.0", - "filenamify": "^2.0.0", - "get-stream": "^3.0.0", - "got": "^7.0.0", - "make-dir": "^1.0.0", - "p-event": "^1.0.0", - "pify": "^3.0.0" - }, - "dependencies": { - "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, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "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 - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "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 - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true - }, - "p-event": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz", - "integrity": "sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=", - "dev": true, - "requires": { - "p-timeout": "^1.1.1" - } }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { - "p-finally": "^1.0.0" + "glob": "^7.1.3" } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true } } }, "dset": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", - "integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", + "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==" }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", "dev": true, "requires": { "readable-stream": "^2.0.2" } }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } }, "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" @@ -5350,13 +24870,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.3.811", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz", - "integrity": "sha512-hv3kgf6YSd+jQ7J+7Kdm44yux/1vxcAwfGV/6M6Nq4E9zJ3Bml/P2+vULCvqLS6Lh9knBCQ7iEMvyeDiGe5EbA==", - "dev": true + "version": "1.4.693", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.693.tgz", + "integrity": "sha512-/if4Ueg0GUQlhCrW2ZlXwDAm40ipuKo+OgeHInlL8sbjt+hzISxZK949fZeJaVsheamrzANXvw1zQTvbxTvSHw==" }, "elegant-spinner": { "version": "2.0.0", @@ -5367,8 +24886,7 @@ "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==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "enabled": { "version": "2.0.0", @@ -5384,15 +24902,15 @@ "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==", - "dev": true, + "devOptional": true, "requires": { "once": "^1.4.0" } }, "enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", + "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -5408,6 +24926,12 @@ "ansi-colors": "^4.1.1" } }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "optional": true + }, "entities": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", @@ -5415,45 +24939,14 @@ "dev": true }, "env-ci": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-5.4.0.tgz", - "integrity": "sha512-6Bq7gq+2QCZjCwe2vUXTcecIsjfh71kyNds5nBrpyuyPjgYgGEHlgjkrKSH6LFwJ5PSEwH3r7KXioGreJKcuHA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-5.5.0.tgz", + "integrity": "sha512-o0JdWIbOLP+WJKIUt36hz1ImQQFuN92nhsfTkHHap+J8CiI8WgGpH/a9jEGHh4/TU5BUUGjlnKXNoDb57+ne+A==", "dev": true, "requires": { "execa": "^5.0.0", "fromentries": "^1.3.2", "java-properties": "^1.0.0" - }, - "dependencies": { - "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" - } - }, - "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 - }, - "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 - } } }, "error-ex": { @@ -5463,24 +24956,17 @@ "dev": true, "requires": { "is-arrayish": "^0.2.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - } } }, "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "version": "0.10.63", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.63.tgz", + "integrity": "sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ==", "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" } }, "es6-error": { @@ -5492,7 +24978,7 @@ "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "requires": { "d": "1", "es5-ext": "^0.10.35", @@ -5508,22 +24994,10 @@ "ext": "^1.1.2" } }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-html": { "version": "1.0.3", @@ -5533,26 +25007,24 @@ "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 + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "requires": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "source-map": { @@ -5565,170 +25037,163 @@ } }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", + "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "requires": { + "@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": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "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", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "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", - "inquirer": "^7.0.0", "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.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, + "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": { - "ms": "2.1.2" + "color-name": "~1.1.4" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "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==" + }, + "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==" + }, + "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==", "requires": { - "is-glob": "^4.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "requires": { - "type-fest": "^0.8.1" + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "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==" + } } }, - "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 - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "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==" }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, + "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==", "requires": { - "shebang-regex": "^1.0.0" + "is-glob": "^4.0.3" } }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "requires": { - "ansi-regex": "^4.1.0" + "type-fest": "^0.20.2" } }, - "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 + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "isexe": "^2.0.0" + "has-flag": "^4.0.0" } + }, + "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==" } } }, "eslint-plugin-flowtype": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.1.3.tgz", - "integrity": "sha512-UU+BbIxBflqJ171yxbd/HcOktCmOdhXbchIVIq/yBvKpLZXvfzNDOyJGcnuQYLaH840hdoIdU/bqxhoW6I0rIQ==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", "dev": true, "requires": { - "lodash": "^4.17.15", + "lodash": "^4.17.21", "string-natural-compare": "^3.0.1" } }, @@ -5736,36 +25201,42 @@ "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, "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "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==" + }, + "esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", "requires": { - "eslint-visitor-keys": "^1.1.0" + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" } }, - "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 - }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "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==" + } } }, "esprima": { @@ -5778,16 +25249,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" } } }, @@ -5795,30 +25264,26 @@ "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, "requires": { "estraverse": "^5.2.0" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" } } }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "etag": { "version": "1.8.1", @@ -5828,7 +25293,7 @@ "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "requires": { "d": "1", "es5-ext": "~0.10.14" @@ -5837,7 +25302,8 @@ "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==" + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "optional": true }, "eventemitter3": { "version": "3.1.2", @@ -5845,78 +25311,30 @@ "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" }, "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "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.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "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.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "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.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -5935,7 +25353,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -5948,9 +25366,9 @@ }, "dependencies": { "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "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.2", "content-type": "~1.0.4", @@ -5960,20 +25378,12 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, - "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==", - "requires": { - "safe-buffer": "5.2.1" - } - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5982,48 +25392,41 @@ "ms": "2.0.0" } }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { - "side-channel": "^1.0.4" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" } } } }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" - } - } - }, - "ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "requires": { - "mime-db": "^1.28.0" - } + "express-rate-limit": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.11.2.tgz", + "integrity": "sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw==", + "requires": {} }, - "ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "requires": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" + "type": "^2.7.2" } }, "extend": { @@ -6031,111 +25434,6 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "optional": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "optional": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "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, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "optional": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "optional": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, "extract-files": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-11.0.0.tgz", @@ -6143,9 +25441,9 @@ "dev": true }, "extsprintf": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz", - "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" }, "fast-deep-equal": { "version": "3.1.3", @@ -6153,70 +25451,16 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "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", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "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==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "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==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } + "requires": { + "@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" } }, "fast-json-stable-stringify": { @@ -6227,31 +25471,46 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "fast-xml-parser": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.5.tgz", + "integrity": "sha512-sWvP1Pl8H03B8oFJpFR3HE31HUfwtX7Rlf9BNsvdpujD4n7WMhfmu8h9wOV2u+c1k0ZilTADhPqypzx2J690ZQ==", + "optional": true, + "requires": { + "strnum": "^1.0.5" + } }, "fastq": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", - "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", - "dev": true, + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", "requires": { "reusify": "^1.0.4" } }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "requires": { "pend": "~1.2.0" } }, "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==" }, "fetch-blob": { "version": "3.2.0", @@ -6264,67 +25523,45 @@ } }, "fetch-node-website": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/fetch-node-website/-/fetch-node-website-5.0.3.tgz", - "integrity": "sha512-O86T46FUWSOq4AWON39oaT8H90QFKAbmjfOVBhgaS87AFfeW00txz73KTv7QopPWtHBbGdI1S8cIT1VK1OQYLg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/fetch-node-website/-/fetch-node-website-7.3.0.tgz", + "integrity": "sha512-/wayUHbdVUWrD72aqRNNrr6+MHnCkumZgNugN0RfiWJpbNJUdAkMk4Z18MGayGZVVqYXR1RWrV+bIFEt5HuBZg==", "dev": true, "requires": { - "chalk": "^4.0.0", - "cli-progress": "^3.7.0", - "figures": "^3.2.0", - "filter-obj": "^2.0.1", - "got": "^10.7.0", - "jest-validate": "^25.3.0" + "cli-progress": "^3.11.2", + "colors-option": "^4.4.0", + "figures": "^5.0.0", + "got": "^12.3.1", + "is-plain-obj": "^4.1.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "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" - } + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true }, - "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==", + "figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", "dev": true, "requires": { - "color-name": "~1.1.4" + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" } }, - "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==", + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } } } }, @@ -6338,12 +25575,11 @@ } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-stream-rotator": { @@ -6357,51 +25593,27 @@ "file-type": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", "dev": true }, - "filenamify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", - "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", - "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, "filing-cabinet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-3.0.0.tgz", - "integrity": "sha512-o8Qac5qxZ1uVidR4Sd7ZQbbqObFZlqXU4xu1suAYg9PQPcQFNTzOmxQa/MehIDMgIvXHTb42mWPNV9l3eHBPSw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-3.3.1.tgz", + "integrity": "sha512-renEK4Hh6DUl9Vl22Y3cxBq1yh8oNvbAdXnhih0wVpmea+uyKjC9K4QeRjUaybIiIewdzfum+Fg15ZqJ/GyCaA==", "dev": true, "requires": { "app-module-path": "^2.2.0", "commander": "^2.20.3", - "debug": "^4.3.1", - "decomment": "^0.9.3", - "enhanced-resolve": "^5.3.2", + "debug": "^4.3.3", + "enhanced-resolve": "^5.8.3", "is-relative-path": "^1.0.2", "module-definition": "^3.3.1", - "module-lookup-amd": "^7.0.0", - "resolve": "^1.19.0", + "module-lookup-amd": "^7.0.1", + "resolve": "^1.21.0", "resolve-dependency-path": "^2.0.0", "sass-lookup": "^3.0.0", "stylus-lookup": "^3.0.1", + "tsconfig-paths": "^3.10.1", "typescript": "^3.9.7" }, "dependencies": { @@ -6411,52 +25623,27 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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==", + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", "dev": true } } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "optional": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "to-regex-range": "^5.0.1" } }, "filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz", + "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==", "dev": true }, "finalhandler": { @@ -6480,13 +25667,18 @@ "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-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { "commondir": "^1.0.1", @@ -6494,6 +25686,25 @@ "pkg-dir": "^4.1.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" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -6503,6 +25714,33 @@ "semver": "^6.0.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" + } + }, + "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" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -6511,19 +25749,12 @@ } } }, - "find-root": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-0.1.2.tgz", - "integrity": "sha1-mNImfP8ZFsyvJ0OzoO6oHXnX3NE=", - "dev": true - }, "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, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "requires": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, @@ -6536,22 +25767,36 @@ "semver-regex": "^3.1.2" } }, + "firebase-admin": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-12.0.0.tgz", + "integrity": "sha512-wBrrSSsKV++/+O8E7O/C7/wL0nbG/x4Xv4yatz/+sohaZ+LsnWtYUcrd3gZutO86hLpDex7xgyrkKbgulmtVyQ==", + "requires": { + "@fastify/busboy": "^1.2.1", + "@firebase/database-compat": "^1.0.2", + "@firebase/database-types": "^1.0.0", + "@google-cloud/firestore": "^7.1.0", + "@google-cloud/storage": "^7.7.0", + "@types/node": "^20.10.3", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.0.1", + "node-forge": "^1.3.1", + "uuid": "^9.0.0" + } + }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "flatten": { "version": "1.0.3", @@ -6571,16 +25816,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "optional": true + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "foreground-child": { "version": "2.0.0", @@ -6595,40 +25833,18 @@ "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": "3.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", - "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "requires": { "asynckit": "^0.4.0", "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==" - }, - "formdata-node": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.3.2.tgz", - "integrity": "sha512-k7lYJyzDOSL6h917favP8j1L0/wNyylzU+x+1w4p5haGVHNlP58dbpdJhiCUsDbWsa9HwEtLp89obQgXl2e0qg==", - "requires": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.1" - }, - "dependencies": { - "web-streams-polyfill": { - "version": "4.0.0-beta.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.1.tgz", - "integrity": "sha512-3ux37gEX670UUphBF9AMCq8XM6iQ8Ac6A+DSRRjDoRBm1ufCkaCDdNVbaqq60PsEkdNlLKrGtv/YBP4EJXqNtQ==" - } - } - }, "formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -6643,16 +25859,6 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "optional": true, - "requires": { - "map-cache": "^0.2.2" - } - }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -6661,7 +25867,7 @@ "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -6674,6 +25880,11 @@ "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true }, + "fs-capacitor": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-6.2.0.tgz", + "integrity": "sha512-nKcE1UduoSKX27NSZlg879LdQc94OtbOsEmKMN2MBNudXREvijRKx2GEBsTMTfws+BrbkJoEuynbGSVRSpauvw==" + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -6681,14 +25892,35 @@ "dev": true }, "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==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { + "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "fs-readdir-recursive": { @@ -6700,99 +25932,156 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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 + }, + "gauge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.1.tgz", + "integrity": "sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + } + } + }, + "gaxios": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.3.0.tgz", + "integrity": "sha512-p+ggrQw3fBwH2F5N/PAI4k/G/y1art5OxKpb2J2chwNNHM4hHuAOtivjPuirMF4KNKwTTUal/lPfL2+7h2mEcg==", + "optional": true, + "requires": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "optional": true, + "requires": { + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "optional": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, + "gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", "optional": true, "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "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=", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } + "generic-pool": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==" }, "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 + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-amd-module-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-3.0.0.tgz", - "integrity": "sha512-99Q7COuACPfVt18zH9N4VAMyb81S6TUgJm2NgV6ERtkh9VIkAaByZkW530wl3lLN5KTtSrK9jVLxYsoP5hQKsw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-4.1.0.tgz", + "integrity": "sha512-0e/eK6vTGCnSfQ6eYs3wtH05KotJYIP7ZIZEueP/KlA+0dIAEs8bYFvOd/U56w1vfjhJqBagUxVMyy9Tr/cViQ==", "dev": true, "requires": { - "ast-module-types": "^2.3.2", - "node-source-walk": "^4.0.0" + "ast-module-types": "^4.0.0", + "node-source-walk": "^5.0.1" } }, "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==", - "dev": true + "devOptional": 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" - } - }, - "get-mongodb-version": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/get-mongodb-version/-/get-mongodb-version-2.0.1.tgz", - "integrity": "sha512-yTN0UY7VJSSt01QH/aCiqiBjfxcDrEdKeM3uXY6QR3sRARoftx36QT0YNsCQm7FDTgrmDje7bK2C9ClM7SGKDA==", - "dev": true, - "requires": { - "lodash.startswith": "^4.2.1", - "minimist": "^1.1.1", - "mongodb": "*", - "which": "^1.1.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "has-symbols": "^1.0.3" } }, "get-own-enumerable-property-symbols": { @@ -6807,35 +26096,16 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, - "get-proxy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", - "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", - "dev": true, - "requires": { - "npm-conf": "^1.1.0" - } - }, "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, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "optional": true + "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 }, "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" } @@ -6843,7 +26113,7 @@ "git-log-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", - "integrity": "sha1-LmpMGxP8AAKCB7p5WnrDFme5/Uo=", + "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", "dev": true, "requires": { "argv-formatter": "~1.0.0", @@ -6857,7 +26127,7 @@ "split2": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", - "integrity": "sha1-UuLiIdiMdfmnP5BVbiY/+WdysxQ=", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", "dev": true, "requires": { "through2": "~2.0.0" @@ -6876,78 +26146,64 @@ } }, "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, + "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" } }, "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "optional": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } + "is-glob": "^4.0.1" } }, "global-cache-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-cache-dir/-/global-cache-dir-2.0.0.tgz", - "integrity": "sha512-30pvU3e8muclEhc9tt+jRMaywOS3QfNdURflJ5Zv0bohjhcVQpBe5bwRHghGSJORLOKW81/n+3iJvHRHs+/S1Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global-cache-dir/-/global-cache-dir-4.4.0.tgz", + "integrity": "sha512-bk0gI6IbbphRjAaCJJn5H+T/CcEck5B3a5KBO2BXSDzjFSV+API17w8GA7YPJ6IXJiasW8M0VsEIig1PCHdfOQ==", "dev": true, "requires": { "cachedir": "^2.3.0", - "path-exists": "^4.0.0" + "path-exists": "^5.0.0" + }, + "dependencies": { + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + } } }, "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 + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "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" }, "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6965,72 +26221,204 @@ "minimist": "^1.2.5" } }, + "google-auth-library": { + "version": "9.6.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.6.3.tgz", + "integrity": "sha512-4CacM29MLC2eT9Cey5GDVK4Q8t+MMp8+OEdOaqD9MG6b0dOyLORaaeJMPQ7EESVgm/+z5EKYyFLxgzBJlJgyHQ==", + "optional": true, + "requires": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "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" + } + } + } + }, + "google-gax": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.1.tgz", + "integrity": "sha512-qpSfslpwqToIgQ+Tf3MjWIDjYK4UFIZ0uz6nLtttlW9N1NQA4PhGf9tlGo6KDYJ4rgL2w4CjXVd0z5yeNpN/Iw==", + "optional": true, + "requires": { + "@grpc/grpc-js": "~1.10.0", + "@grpc/proto-loader": "^0.7.0", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.0", + "protobufjs": "7.2.6", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "dependencies": { + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, "got": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", - "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", - "dev": true, - "requires": { - "@sindresorhus/is": "^2.0.0", - "@szmarczak/http-timer": "^4.0.0", - "@types/cacheable-request": "^6.0.1", - "cacheable-lookup": "^2.0.0", - "cacheable-request": "^7.0.1", - "decompress-response": "^5.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^5.0.0", - "lowercase-keys": "^2.0.0", - "mimic-response": "^2.1.0", - "p-cancelable": "^2.0.0", - "p-event": "^4.0.0", - "responselike": "^2.0.0", - "to-readable-stream": "^2.0.0", - "type-fest": "^0.10.0" + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.3.tgz", + "integrity": "sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==", + "dev": true, + "requires": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "dependencies": { + "form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true + } } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "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==" + }, "graphql": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", - "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==" + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==" }, "graphql-list-fields": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/graphql-list-fields/-/graphql-list-fields-2.0.2.tgz", - "integrity": "sha512-9TSAwcVA3KWw7JWYep5NCk2aw3wl1ayLtbMpmG7l26vh1FZ+gZexNPP+XJfUFyJa71UU0zcKSgtgpsrsA3Xv9Q==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/graphql-list-fields/-/graphql-list-fields-2.0.4.tgz", + "integrity": "sha512-q3prnhAL/dBsD+vaGr83B8DzkBijg+Yh+lbt7qp2dW1fpuO+q/upzDXvFJstVsSAA8m11MHGkSxxyxXeLou4MA==" }, "graphql-relay": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/graphql-relay/-/graphql-relay-0.10.0.tgz", - "integrity": "sha512-44yBuw2/DLNEiMypbNZBt1yMDbBmyVPVesPywnteGGALiBmdyy1JP8jSg8ClLePg8ZZxk0O4BLhd1a6U/1jDOQ==" + "integrity": "sha512-44yBuw2/DLNEiMypbNZBt1yMDbBmyVPVesPywnteGGALiBmdyy1JP8jSg8ClLePg8ZZxk0O4BLhd1a6U/1jDOQ==", + "requires": {} }, "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==", + "dev": true, "requires": { "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - } } }, - "graphviz": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/graphviz/-/graphviz-0.0.9.tgz", - "integrity": "sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg==", - "dev": true, + "graphql-upload": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/graphql-upload/-/graphql-upload-15.0.2.tgz", + "integrity": "sha512-ufJAkZJBKWRDD/4wJR3VZMy9QWTwqIYIciPtCEF5fCNgWF+V1p7uIgz+bP2YYLiS4OJBhCKR8rnqE/Wg3XPUiw==", + "requires": { + "@types/busboy": "^1.5.0", + "@types/node": "*", + "@types/object-path": "^0.11.1", + "busboy": "^1.6.0", + "fs-capacitor": "^6.2.0", + "http-errors": "^2.0.0", + "object-path": "^0.11.8" + } + }, + "gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "optional": true, "requires": { - "temp": "~0.4.0" + "gaxios": "^6.0.0", + "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" + } + } } }, "handlebars": { @@ -7057,7 +26445,7 @@ "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", @@ -7085,77 +26473,17 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "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==" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "optional": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "optional": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "hasha": { "version": "5.2.2", @@ -7175,6 +26503,12 @@ } } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -7191,9 +26525,9 @@ "dev": true }, "hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -7216,6 +26550,29 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "html-minifier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", + "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "dev": true, + "requires": { + "camel-case": "^3.0.0", + "clean-css": "^4.2.1", + "commander": "^2.19.0", + "he": "^1.2.0", + "param-case": "^2.1.1", + "relateurl": "^0.2.7", + "uglify-js": "^3.5.1" + }, + "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==", + "dev": true + } + } + }, "htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", @@ -7244,9 +26601,9 @@ } }, "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==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, "http-errors": { @@ -7261,6 +26618,11 @@ "toidentifier": "1.0.1" } }, + "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==" + }, "http-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", @@ -7270,201 +26632,57 @@ "@tootallnate/once": "1", "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 - } } }, "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", "sshpk": "^1.7.0" } }, - "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==", + "http2-wrapper": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", "dev": true, "requires": { - "agent-base": "6", - "debug": "4" + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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==", + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true } } }, + "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==", + "devOptional": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "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 }, "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "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" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "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==", - "dev": true - }, - "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" - } - }, - "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, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "locate-path": { - "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": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "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, - "requires": { - "p-limit": "^3.0.2" - } - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true }, "iconv-lite": { "version": "0.4.24", @@ -7475,26 +26693,28 @@ } }, "idb-keyval": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-5.0.6.tgz", - "integrity": "sha512-6lJuVbwyo82mKSH6Wq2eHkt9LcbwHAelMIcMe0tP4p20Pod7tTxq9zf0ge2n/YDfMOpDryerfmmYyuQiaFaKOg==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.0.tgz", + "integrity": "sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==", + "requires": { + "safari-14-idb-fix": "^3.0.0" + } }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true }, "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 + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==" }, "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, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7520,8 +26740,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "indent-string": { "version": "4.0.0", @@ -7532,14 +26751,13 @@ "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -7556,266 +26774,70 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, - "inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "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" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "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==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "intersect": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/intersect/-/intersect-1.0.1.tgz", - "integrity": "sha1-MyZQ4QhU2MCsWMGSvcJ6i/fnoww=" + "integrity": "sha512-qsc720yevCO+4NydrJWgEWKccAQwTOvj2m73O/VBA6iUL2HGZJ9XqBiyraNrBXX/W1IAjdpXdRZk24sq8TzBRg==" }, "into-stream": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", - "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", - "dev": true, - "requires": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" - } - }, - "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": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" - }, - "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-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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==" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", "dev": true, - "optional": true, "requires": { - "binary-extensions": "^1.0.0" + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "optional": true + "ip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" }, - "is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } + "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-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "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 + }, + "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==", "dev": true, "optional": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "binary-extensions": "^2.0.0" } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "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==", "dev": true, - "optional": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "optional": true - } + "has": "^1.0.3" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "optional": true - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } + "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-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } @@ -7826,71 +26848,22 @@ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true }, - "is-mongodb-running": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-mongodb-running/-/is-mongodb-running-1.0.2.tgz", - "integrity": "sha512-EslN8MErcBPExb+iK4RnG1n28JGjByA2Rm3YPmdHDGCRd7Hc2uvqshyVMAJXxbDSxRMy8vhxims2oRqQUeGJeA==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "debug": ">= 2.6.9", - "figures": "^2.0.0", - "lodash": "^4.17.10", - "lsof": "^0.1.0", - "minimist": "^1.2.0", - "node-netstat": "^1.4.2", - "ps-node": "^0.1.6" - }, - "dependencies": { - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - } - } - }, "is-natural-number": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", "dev": true }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, "is-path-cwd": { @@ -7902,33 +26875,19 @@ "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 + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true }, "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "optional": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true }, "is-promise": { "version": "2.2.2", @@ -7938,19 +26897,13 @@ "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "dev": true }, "is-relative-path": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-relative-path/-/is-relative-path-1.0.2.tgz", - "integrity": "sha1-CRtGoNZ8HtD+hfH4z93gBrslHUY=", - "dev": true - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "integrity": "sha512-i1h+y50g+0hRbBD+dbnInl3JlJ702aar58snAeX+MxBAPvzXGej7sYoPMhlnykabt0ZzCJNBEyzMlekuQZN7fA==", "dev": true }, "is-stream": { @@ -7961,7 +26914,7 @@ "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", "dev": true, "requires": { "text-extensions": "^1.0.0" @@ -7970,7 +26923,7 @@ "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-unicode-supported": { "version": "0.1.0", @@ -7996,27 +26949,21 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "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==", + "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "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==" }, "issue-parser": { "version": "6.0.0", @@ -8032,9 +26979,9 @@ } }, "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "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 }, "istanbul-lib-hook": { @@ -8067,29 +27014,19 @@ } }, "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, "requires": { "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", "p-map": "^3.0.0", "rimraf": "^3.0.0", - "uuid": "^3.3.3" + "uuid": "^8.3.2" }, "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, "p-map": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", @@ -8099,25 +27036,10 @@ "aggregate-error": "^3.0.0" } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true } } @@ -8166,9 +27088,9 @@ } }, "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "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", @@ -8176,21 +27098,6 @@ "source-map": "^0.6.1" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8200,25 +27107,15 @@ } }, "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "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", "istanbul-lib-report": "^3.0.0" } }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, "iterall": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", @@ -8227,163 +27124,92 @@ "jasmine": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.5.0.tgz", - "integrity": "sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "jasmine-core": "~3.5.0" - } - }, - "jasmine-core": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", - "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", - "dev": true - }, - "jasmine-spec-reporter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", - "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", - "dev": true, - "requires": { - "colors": "1.4.0" - } - }, - "java-properties": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", - "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", - "dev": true - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "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" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "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==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "integrity": "sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "jasmine-core": "~3.5.0" } }, - "jose": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz", - "integrity": "sha512-FVoPY7SflDodE4lknJmbAHSUjLCzE2H1F6MS0RYKMQ8SR+lNccpMf8R4eqkNYyyUjR5qZReOzZo5C5YiHOCjjg==", + "jasmine-core": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz", + "integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==", + "dev": true + }, + "jasmine-spec-reporter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", + "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", + "dev": true, "requires": { - "@panva/asn1.js": "^1.0.0" + "colors": "1.4.0" } }, + "java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true + }, + "jose": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" + }, + "js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "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==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "js2xmlparser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", - "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "dev": true, "requires": { - "xmlcreate": "^2.0.3" + "xmlcreate": "^2.0.4" } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "jsdoc": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.3.tgz", - "integrity": "sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", "dev": true, "requires": { - "@babel/parser": "^7.4.4", - "bluebird": "^3.5.4", - "catharsis": "^0.8.11", + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.0", + "js2xmlparser": "^4.0.2", "klaw": "^3.0.0", - "markdown-it": "^8.4.2", - "markdown-it-anchor": "^5.0.2", - "marked": "^0.7.0", - "mkdirp": "^0.5.1", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", "requizzle": "^0.2.3", - "strip-json-comments": "^3.0.1", - "taffydb": "2.6.2", - "underscore": "~1.9.1" + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" }, "dependencies": { "escape-string-regexp": { @@ -8391,6 +27217,12 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true } } }, @@ -8407,14 +27239,22 @@ "jsdoc-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz", - "integrity": "sha1-hCRCjVtWOtjFx/vsB5uaiwnI3Po=", + "integrity": "sha512-CMFgT3K8GbmChWEfLWe6jlv9x33E8wLPzBjxIlh/eHLMcnDF+TF3CL265ZGBe029o1QdFepwVrQu0WuqqNPncg==", "dev": true }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "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, + "requires": { + "bignumber.js": "^9.0.0" + } }, "json-buffer": { "version": "3.0.1", @@ -8435,9 +27275,9 @@ "dev": true }, "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, "json-schema-traverse": { "version": "0.4.1", @@ -8447,85 +27287,88 @@ "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=", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "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": "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" - } + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", "requires": { "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", + "lodash": "^4.17.21", "ms": "^2.1.1", - "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==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } + "semver": "^7.3.8" } }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" }, "dependencies": { - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "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==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } } } }, + "jssha": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.3.1.tgz", + "integrity": "sha512-VCMZj12FCFMQYcFLPRm/0lOBbLi8uM2BhXPTqw3U4YAfs4AZfiApOoBLoN8cQE60Z50m1MYMTQVCfgF/KaCVhQ==" + }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -8537,31 +27380,16 @@ } }, "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": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", "requires": { - "@types/express": "^4.17.13", - "@types/jsonwebtoken": "^8.5.8", + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", "debug": "^4.3.4", - "jose": "^2.0.5", + "jose": "^4.14.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==" - } + "lru-memoizer": "^2.2.0" } }, "jws": { @@ -8573,27 +27401,15 @@ "safe-buffer": "^5.0.1" } }, - "key-tree-store": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/key-tree-store/-/key-tree-store-1.3.0.tgz", - "integrity": "sha1-XqKa/CUppCWThDfWlVtxTOapeR8=", - "dev": true - }, "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", "dev": true, "requires": { "json-buffer": "3.0.1" } }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, "klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", @@ -8603,57 +27419,48 @@ "graceful-fs": "^4.1.9" } }, + "klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, "kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" }, - "ldap-filter": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/ldap-filter/-/ldap-filter-0.3.3.tgz", - "integrity": "sha512-/tFkx5WIn4HuO+6w9lsfxq4FN3O+fDZeO9Mek8dCD8rTUpqzRa766BOBO7BcGkn3X86m5+cBm1/2S/Shzz7gMg==", - "requires": { - "assert-plus": "^1.0.0" - } - }, "ldapjs": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-2.3.3.tgz", - "integrity": "sha512-75QiiLJV/PQqtpH+HGls44dXweviFwQ6SiIK27EqzKQ5jU/7UFrl2E5nLdQ3IYRBzJ/AVFJI66u0MZ0uofKYwg==", - "requires": { - "abstract-logging": "^2.0.0", - "asn1": "^0.2.4", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-3.0.7.tgz", + "integrity": "sha512-1ky+WrN+4CFMuoekUOv7Y1037XWdjKpu0xAPwSP+9KdvmV9PG+qOKlssDV6a+U32apwxdD3is/BZcWOYzN30cg==", + "requires": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/messages": "^1.3.0", + "@ldapjs/protocol": "^1.2.1", + "abstract-logging": "^2.0.1", "assert-plus": "^1.0.0", "backoff": "^2.5.0", - "ldap-filter": "^0.3.3", "once": "^1.4.0", - "vasync": "^2.2.0", - "verror": "^1.8.1" - } - }, - "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 - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "requires": { - "leven": "^3.1.0" + "vasync": "^2.2.1", + "verror": "^1.10.1" } }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "limiter": { @@ -8662,15 +27469,15 @@ "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "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 }, "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==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", "dev": true, "requires": { "uc.micro": "^1.0.1" @@ -8706,15 +27513,6 @@ "color-convert": "^2.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -8740,22 +27538,49 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "dev": true, "requires": { - "ms": "2.1.2" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" } }, - "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==", + "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, "requires": { - "to-regex-range": "^5.0.1" + "pump": "^3.0.0" } }, "has-flag": { @@ -8764,26 +27589,10 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "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==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "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": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true }, "supports-color": { @@ -8794,15 +27603,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "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==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -8888,7 +27688,7 @@ "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -8900,7 +27700,7 @@ "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, "requires": { "error-ex": "^1.3.1", @@ -8910,24 +27710,23 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true } } }, "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, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "requires": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" } }, "lodash": { @@ -8938,19 +27737,25 @@ "lodash.assignin": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", - "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==", "dev": true }, "lodash.bind": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", - "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "optional": true + }, "lodash.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", - "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", "dev": true }, "lodash.clonedeep": { @@ -8958,153 +27763,128 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "dev": true }, "lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", "dev": true }, "lodash.filter": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", - "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==", "dev": true }, "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", "dev": true }, "lodash.foreach": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", - "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", "dev": true }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, "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==", + "dev": true }, "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==", + "dev": true }, "lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", "dev": true }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "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-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "lodash.pad": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", - "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=", + "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", "dev": true }, "lodash.padend": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", + "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", "dev": true }, "lodash.padstart": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", - "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=", + "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", "dev": true }, "lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", "dev": true }, "lodash.reduce": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", - "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==", "dev": true }, "lodash.reject": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", - "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==", "dev": true }, "lodash.some": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", "dev": true }, - "lodash.startswith": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.startswith/-/lodash.startswith-4.2.1.tgz", - "integrity": "sha1-xZjErc4YiiflMUVzHNxsDnF3YAw=", - "dev": true + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, "lodash.uniqby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", "dev": true }, "log-symbols": { @@ -9189,12 +27969,6 @@ "color-convert": "^2.0.1" } }, - "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 - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -9210,12 +27984,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "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==", - "dev": true - }, "slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -9230,24 +27998,27 @@ } }, "logform": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.0.tgz", - "integrity": "sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.2.tgz", + "integrity": "sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==", "requires": { "@colors/colors": "1.5.0", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.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==" - } } }, + "loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==" + }, + "long": { + "version": "4.0.0", + "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", @@ -9257,21 +28028,27 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "dev": true + }, "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true }, "lru-cache": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.12.0.tgz", - "integrity": "sha512-OIP3DwzRZDfLg9B9VP/huWBlpvbkmbfiBy8xmsXp4RPmE4A3MhwNozc5ZJ3fWnSg8fDcdlE/neRTPG2ycEKliw==" + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==" }, "lru-memoizer": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", - "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", + "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", "requires": { "lodash.clonedeep": "^4.5.0", "lru-cache": "~4.0.0" @@ -9296,44 +28073,38 @@ "lru-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", "requires": { "es5-ext": "~0.10.2" } }, - "lsof": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lsof/-/lsof-0.1.0.tgz", - "integrity": "sha1-rALU2HYGIB8TZLr7FcSRz9WuMJI=", - "dev": true - }, "madge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/madge/-/madge-5.0.1.tgz", - "integrity": "sha512-krmSWL9Hkgub74bOjnjWRoFPAJvPwSG6Dbta06qhWOq6X/n/FPzO3ESZvbFYVIvG2g4UHXvCJN1b+RZLaSs9nA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/madge/-/madge-6.1.0.tgz", + "integrity": "sha512-irWhT5RpFOc6lkzGHKLihonCVgM0YtfNUh4IrFeW3EqHpnt/JHUG3z26j8PeJEktCGB4tmGOOOJi1Rl/ACWucQ==", "dev": true, "requires": { "chalk": "^4.1.1", "commander": "^7.2.0", "commondir": "^1.0.1", "debug": "^4.3.1", - "dependency-tree": "^8.1.1", - "detective-amd": "^3.1.0", - "detective-cjs": "^3.1.1", - "detective-es6": "^2.2.0", + "dependency-tree": "^9.0.0", + "detective-amd": "^4.0.1", + "detective-cjs": "^4.0.0", + "detective-es6": "^3.0.0", "detective-less": "^1.0.2", - "detective-postcss": "^5.0.0", - "detective-sass": "^3.0.1", - "detective-scss": "^2.0.1", - "detective-stylus": "^1.0.0", - "detective-typescript": "^7.0.0", - "graphviz": "0.0.9", + "detective-postcss": "^6.1.0", + "detective-sass": "^4.0.1", + "detective-scss": "^3.0.0", + "detective-stylus": "^2.0.1", + "detective-typescript": "^9.0.0", "ora": "^5.4.1", "pluralize": "^8.0.0", "precinct": "^8.1.0", "pretty-ms": "^7.0.1", "rc": "^1.2.7", - "typescript": "^3.9.5", + "stream-to-array": "^2.3.0", + "ts-graphviz": "^1.5.0", "walkdir": "^0.4.1" }, "dependencies": { @@ -9377,27 +28148,12 @@ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "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 - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9427,151 +28183,56 @@ } } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "optional": true - }, "map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "optional": true, - "requires": { - "object-visit": "^1.0.0" - } - }, "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", "dev": true, "requires": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } } }, "markdown-it-anchor": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", - "dev": true + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "requires": {} }, "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true }, - "marked-terminal": { - "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": "^4.3.1", - "cardinal": "^2.1.1", - "chalk": "^4.1.0", - "cli-table3": "^0.6.0", - "node-emoji": "^1.10.0", - "supports-hyperlinks": "^2.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "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" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "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==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", "dev": true }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - }, - "dependencies": { - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - } - } + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memory-pager": { "version": "1.5.0", @@ -9603,12 +28264,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true } } }, @@ -9635,25 +28290,13 @@ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "optional": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mime": { @@ -9662,16 +28305,16 @@ "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==" }, "mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" + "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.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "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.49.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -9681,9 +28324,9 @@ "dev": true }, "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "dev": true }, "min-indent": { @@ -9693,18 +28336,17 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, + "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==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, "minimist-options": { @@ -9716,47 +28358,57 @@ "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } } }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, - "optional": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "minipass": "^3.0.0", + "yallist": "^4.0.0" }, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "optional": true, "requires": { - "is-plain-object": "^2.0.4" + "yallist": "^4.0.0" } } } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" } }, "mock-files-adapter": { - "version": "file:spec/dependencies/mock-files-adapter", - "dev": true + "version": "file:spec/dependencies/mock-files-adapter" }, "mock-mail-adapter": { - "version": "file:spec/dependencies/mock-mail-adapter", - "dev": true + "version": "file:spec/dependencies/mock-mail-adapter" }, "modify-values": { "version": "1.0.1", @@ -9765,13 +28417,30 @@ "dev": true }, "module-definition": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-3.3.1.tgz", - "integrity": "sha512-kLidGPwQ2yq484nSD+D3JoJp4Etc0Ox9P0L34Pu/cU4X4HcG7k7p62XI5BBuvURWMRX3RPyuhOcBHbKus+UH4A==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-3.4.0.tgz", + "integrity": "sha512-XxJ88R1v458pifaSkPNLUTdSPNVGMP2SXVncVmApGO+gAfrLANiYe6JofymCzVceGOMwQE2xogxBSc8uB7XegA==", "dev": true, "requires": { - "ast-module-types": "^2.7.1", + "ast-module-types": "^3.0.0", "node-source-walk": "^4.0.0" + }, + "dependencies": { + "ast-module-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-3.0.0.tgz", + "integrity": "sha512-CMxMCOCS+4D+DkOQfuZf+vLrSEmY/7xtORwdxs4wtcC1wVgvk2MqFFTwQCFhvWsI4KPU9lcWXPI8DgRiz+xetQ==", + "dev": true + }, + "node-source-walk": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.3.0.tgz", + "integrity": "sha512-8Q1hXew6ETzqKRAs3jjLioSxNfT1cx74ooiF8RlAONwVMcfq+UdzLC2eB5qcPldUxaE5w3ytLkrmV1TGddhZTA==", + "dev": true, + "requires": { + "@babel/parser": "^7.0.0" + } + } } }, "module-lookup-amd": { @@ -9792,21 +28461,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 } } }, @@ -9816,120 +28470,29 @@ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "mongodb": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.10.0.tgz", - "integrity": "sha512-My2QxLTw0Cc1O9gih0mz4mqo145Jq4rLAQx0Glk/Ha9iYBzYpt4I2QFNRIh35uNFNfe8KFQcdwY1/HKxXBkinw==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.0.tgz", + "integrity": "sha512-g+GCMHN1CoRUA+wb1Agv0TI4YTSiWr42B5ulkiAfLLHitGK1R+PkSAf3Lr5rPZwi/3F04LiaZEW0Kxro9Fi2TA==", "requires": { - "bson": "^4.7.0", - "denque": "^2.1.0", - "mongodb-connection-string-url": "^2.5.3", - "saslprep": "^1.0.3", - "socks": "^2.7.0" - }, - "dependencies": { - "bson": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.0.tgz", - "integrity": "sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==", - "requires": { - "buffer": "^5.6.0" - } - }, - "denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" - } + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^5.5.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" } }, "mongodb-connection-string-url": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.4.tgz", - "integrity": "sha512-SeAxuWs0ez3iI3vvmLk/j2y+zHwigTDKQhtdxTgt5ZCOQQS5+HW4g45/Xw5vzzbn7oQXCNQ24Z40AkJsizEy7w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", "requires": { "@types/whatwg-url": "^8.2.1", "whatwg-url": "^11.0.0" - }, - "dependencies": { - "tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "requires": { - "punycode": "^2.1.1" - } - }, - "webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" - }, - "whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "requires": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - } - } - } - }, - "mongodb-core": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.7.tgz", - "integrity": "sha512-WypKdLxFNPOH/Jy6i9z47IjG2wIldA54iDZBmHMINcgKOUcWJh8og+Wix76oGd7EyYkHJKssQ2FAOw5Su/n4XQ==", - "dev": true, - "requires": { - "bson": "^1.1.1", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" - } - }, - "mongodb-dbpath": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/mongodb-dbpath/-/mongodb-dbpath-0.0.1.tgz", - "integrity": "sha1-4BMsZ3sbncgwBFEW0Yrbf2kk8XU=", - "dev": true, - "requires": { - "async": "^1.4.0", - "debug": "^2.1.1", - "minimist": "^1.1.1", - "mkdirp": "^0.5.1", - "untildify": "^1.0.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "untildify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-1.0.0.tgz", - "integrity": "sha1-TYAx0YBvT718QrAjeq8hNoYmJjU=", - "dev": true, - "requires": { - "user-home": "^1.0.0" - } - } } }, "mongodb-download-url": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/mongodb-download-url/-/mongodb-download-url-1.1.1.tgz", - "integrity": "sha512-LTZcnD1By5G80DFgLEnCZhrl0TFINfcVT/iGgrjCNj7EYZjEvhtlE9Ik19Q5PebrULWqWA8cVwYtDOVBsLcPgw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mongodb-download-url/-/mongodb-download-url-1.4.1.tgz", + "integrity": "sha512-OC0EGXiYTwZNcLq2U7Hbt1MDSPQR57/Kput4+W0F2kwVOa0HwWW4oY6DS1gOLlIeVOsihRKKH9EPNnc/BxF7UA==", "dev": true, "requires": { "debug": "^4.1.1", @@ -9938,125 +28501,123 @@ "semver": "^7.1.1" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "requires": { - "ms": "2.1.2" + "whatwg-url": "^5.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==", + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "requires": { - "whatwg-url": "^5.0.0" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } } } }, "mongodb-runner": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/mongodb-runner/-/mongodb-runner-4.8.1.tgz", - "integrity": "sha512-1jv7EEyh+ajvGmLwDMXY5BjT/Xqdxgf+AwPK99JHhgeoAISffS3l9Z1c/IIOsSCulMlL7KlR10TyUdzSHZqMhg==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/mongodb-runner/-/mongodb-runner-5.4.4.tgz", + "integrity": "sha512-bODXH7sOMRXbpVceIR8zLnEgg9kv1eXW60pxW5dfNShkjWd+7wmalJY/Dm9LG1tcL7+O5H7lTZH+s32IWg+FVA==", "dev": true, "requires": { - "async": "^3.1.0", - "clui": "^0.3.6", - "debug": "^4.1.1", - "fs-extra": "^8.1.0", - "is-mongodb-running": "^1.0.1", - "lodash.defaults": "^4.2.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "mongodb": "^3.4.0", - "mongodb-dbpath": "^0.0.1", - "mongodb-tools": "github:mongodb-js/mongodb-tools#0d1a90f49796c41f6d47c7c7999fe384014a16a0", - "mongodb-version-manager": "^1.4.3", - "untildify": "^4.0.0", - "which": "^2.0.1" + "@mongodb-js/mongodb-downloader": "^0.2.8", + "debug": "^4.3.4", + "mongodb": "^5.6.0", + "mongodb-connection-string-url": "^2.6.0", + "yargs": "^17.7.2" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "ms": "2.1.2" + "color-convert": "^2.0.1" } }, - "mongodb": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.3.tgz", - "integrity": "sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==", + "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, "requires": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.1.8", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "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==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "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==", "dev": true - } - } - }, - "mongodb-tools": { - "version": "github:mongodb-js/mongodb-tools#0d1a90f49796c41f6d47c7c7999fe384014a16a0", - "from": "github:mongodb-js/mongodb-tools#0d1a90f49796c41f6d47c7c7999fe384014a16a0", - "dev": true, - "requires": { - "debug": "^2.2.0", - "lodash": "^4.17.12", - "mkdirp": "0.5.0", - "mongodb-core": "*", - "rimraf": "2.2.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ms": "2.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { - "minimist": "0.0.8" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" } }, - "rimraf": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz", - "integrity": "sha1-xZWXVpsU2VatKcrMQr3d9fDqT0w=", + "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 } } @@ -10064,7 +28625,7 @@ "mongodb-version-list": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/mongodb-version-list/-/mongodb-version-list-1.0.0.tgz", - "integrity": "sha1-8lAxz83W8UWx3o/OKk6+wCiLtKQ=", + "integrity": "sha512-F3kIABEMNjg3ZAX4SRbO1QPmhpP4NX2IgJq+lcUKidducTOVJafXJ+E+pMkgpU0xumC8QYbIZJ+8y4GZys9E4g==", "dev": true, "requires": { "cheerio": "^0.22.0", @@ -10087,7 +28648,7 @@ "fs-extra": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -10098,7 +28659,7 @@ "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", "dev": true, "requires": { "graceful-fs": "^4.1.6" @@ -10107,44 +28668,18 @@ "klaw": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", "dev": true, "requires": { "graceful-fs": "^4.1.9" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true - } - } - }, - "mongodb-version-manager": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/mongodb-version-manager/-/mongodb-version-manager-1.4.6.tgz", - "integrity": "sha512-UxXZy7iqHUa039Bp8e1Y2tSLh/X/JtHRqnlcVkqNEWpX/5ETPaKwrT7QIVZc1Tk5tEkQXjRHd6nQtUjcemOHmA==", - "dev": true, - "requires": { - "ampersand-state": "^5.0.3", - "async": "^3.1.0", - "chalk": "^2.1.0", - "debug": ">= 2.6.9 < 3.0.0 || >= ^3.1.0", - "docopt": "^0.6.2", - "download": "^6.2.5", - "figures": "^3.2.0", - "fs-extra": "^8.1.0", - "get-mongodb-version": "^2.0.1", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.1.1", - "mongodb-download-url": "^1.0.0", - "mongodb-version-list": "^1.0.0", - "semver": "^5.3.0", - "tildify": "^2.0.0", - "untildify": "^4.0.0" - }, - "dependencies": { + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -10154,59 +28689,25 @@ } }, "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", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==" }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true, - "optional": true - }, "nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "optional": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "negotiator": { "version": "0.6.3", @@ -10222,24 +28723,34 @@ "nerf-dart": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", - "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", "dev": true }, "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, + "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==", "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==" + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true }, "node-emoji": { "version": "1.11.0", @@ -10262,18 +28773,9 @@ } }, "node-forge": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz", - "integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==" - }, - "node-netstat": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/node-netstat/-/node-netstat-1.8.0.tgz", - "integrity": "sha512-P1a5Sh9FfjTXxI6hC9q/Nqre8kT63FQxBCr1qz5ffk76EkQBH62+XEhIhlzfz6Bz+FRwOFqidW2FDGXnOXvyJQ==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" }, "node-preload": { "version": "0.2.1", @@ -10285,18 +28787,17 @@ } }, "node-releases": { - "version": "1.1.75", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", - "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", - "dev": true + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node-source-walk": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.2.0.tgz", - "integrity": "sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-5.0.2.tgz", + "integrity": "sha512-Y4jr/8SRS5hzEdZ7SGuvZGwfORvNsSsNRwDXx5WisiqzsVfeftDvRgfeqWNgZvWSJbgubTRVRYBzK6UO+ErqjA==", "dev": true, "requires": { - "@babel/parser": "^7.0.0" + "@babel/parser": "^7.21.4" } }, "normalize-package-data": { @@ -10329,76 +28830,76 @@ "integrity": "sha512-120p116CE8VMMZ+hk8IAb1inCPk4Dj3VZw29/n2g6UI77urJKVYb7FZUDW8hY+EBnfsjI/2yrobBgFyzo7YpVQ==", "dev": true, "requires": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^2.9.0", - "@npmcli/ci-detect": "^1.2.0", - "@npmcli/config": "^2.3.0", - "@npmcli/map-workspaces": "^1.0.4", - "@npmcli/package-json": "^1.0.1", - "@npmcli/run-script": "^1.8.6", - "abbrev": "~1.1.1", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "archy": "~1.0.0", - "cacache": "^15.3.0", - "chalk": "^4.1.2", - "chownr": "^2.0.0", - "cli-columns": "^3.1.2", - "cli-table3": "^0.6.0", - "columnify": "~1.5.4", - "fastest-levenshtein": "^1.0.12", - "glob": "^7.2.0", - "graceful-fs": "^4.2.8", - "hosted-git-info": "^4.0.2", - "ini": "^2.0.0", - "init-package-json": "^2.0.5", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^2.3.1", - "libnpmaccess": "^4.0.2", - "libnpmdiff": "^2.0.4", - "libnpmexec": "^2.0.1", - "libnpmfund": "^1.1.0", - "libnpmhook": "^6.0.2", - "libnpmorg": "^2.0.2", - "libnpmpack": "^2.0.1", - "libnpmpublish": "^4.0.1", - "libnpmsearch": "^3.1.1", - "libnpmteam": "^2.0.3", - "libnpmversion": "^1.2.1", - "make-fetch-happen": "^9.1.0", - "minipass": "^3.1.3", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "ms": "^2.1.2", - "node-gyp": "^7.1.2", - "nopt": "^5.0.0", - "npm-audit-report": "^2.1.5", - "npm-install-checks": "^4.0.0", - "npm-package-arg": "^8.1.5", - "npm-pick-manifest": "^6.1.1", - "npm-profile": "^5.0.3", - "npm-registry-fetch": "^11.0.0", - "npm-user-validate": "^1.0.1", - "npmlog": "^5.0.1", - "opener": "^1.5.2", - "pacote": "^11.3.5", - "parse-conflict-json": "^1.1.1", - "qrcode-terminal": "^0.12.0", - "read": "~1.0.7", - "read-package-json": "^4.1.1", - "read-package-json-fast": "^2.0.3", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "ssri": "^8.0.1", - "tar": "^6.1.11", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^1.0.4", - "validate-npm-package-name": "~3.0.0", - "which": "^2.0.2", - "write-file-atomic": "^3.0.3" + "@isaacs/string-locale-compare": "*", + "@npmcli/arborist": "*", + "@npmcli/ci-detect": "*", + "@npmcli/config": "*", + "@npmcli/map-workspaces": "*", + "@npmcli/package-json": "*", + "@npmcli/run-script": "*", + "abbrev": "*", + "ansicolors": "*", + "ansistyles": "*", + "archy": "*", + "cacache": "*", + "chalk": "*", + "chownr": "*", + "cli-columns": "*", + "cli-table3": "*", + "columnify": "*", + "fastest-levenshtein": "*", + "glob": "*", + "graceful-fs": "*", + "hosted-git-info": "*", + "ini": "*", + "init-package-json": "*", + "is-cidr": "*", + "json-parse-even-better-errors": "*", + "libnpmaccess": "*", + "libnpmdiff": "*", + "libnpmexec": "*", + "libnpmfund": "*", + "libnpmhook": "*", + "libnpmorg": "*", + "libnpmpack": "*", + "libnpmpublish": "*", + "libnpmsearch": "*", + "libnpmteam": "*", + "libnpmversion": "*", + "make-fetch-happen": "*", + "minipass": "*", + "minipass-pipeline": "*", + "mkdirp": "*", + "mkdirp-infer-owner": "*", + "ms": "*", + "node-gyp": "*", + "nopt": "*", + "npm-audit-report": "*", + "npm-install-checks": "*", + "npm-package-arg": "*", + "npm-pick-manifest": "*", + "npm-profile": "*", + "npm-registry-fetch": "*", + "npm-user-validate": "*", + "npmlog": "*", + "opener": "*", + "pacote": "*", + "parse-conflict-json": "*", + "qrcode-terminal": "*", + "read": "*", + "read-package-json": "*", + "read-package-json-fast": "*", + "readdir-scoped-modules": "*", + "rimraf": "*", + "semver": "*", + "ssri": "*", + "tar": "*", + "text-table": "*", + "tiny-relative-date": "*", + "treeverse": "*", + "validate-npm-package-name": "*", + "which": "*", + "write-file-atomic": "*" }, "dependencies": { "@gar/promisify": { @@ -12196,6 +30697,14 @@ "minipass": "^3.1.1" } }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "2.1.1", "bundled": true, @@ -12220,14 +30729,6 @@ } } }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "stringify-package": { "version": "1.0.1", "bundled": true, @@ -12411,24 +30912,6 @@ } } }, - "npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "dev": true, - "requires": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -12439,14 +30922,21 @@ } }, "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-7.0.1.tgz", + "integrity": "sha512-uJ0YFk/mCQpLBt+bxN88AKd+gyqZvZDbtiNxk6Waqcj2aPRyfVx8ITawkyQynxUagInjdYT1+qj4NfA5KJJUxg==", "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "^4.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^5.0.0", + "set-blocking": "^2.0.0" + }, + "dependencies": { + "are-we-there-yet": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-4.0.2.tgz", + "integrity": "sha512-ncSWAawFhKMJDTdoAeOV+jyW1VCMj5QIAwULIBV0SSR7B/RLPPEQiknKcg/RIIZlUQrxELpsxMiTUoAQ4sIUyg==" + } } }, "nth-check": { @@ -12458,11 +30948,6 @@ "boolbase": "~1.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, "nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", @@ -12498,6 +30983,25 @@ "yargs": "^15.0.2" }, "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" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -12507,6 +31011,24 @@ "semver": "^6.0.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-map": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", @@ -12522,132 +31044,38 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "optional": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" - }, - "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==" + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "optional": true, - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } - } + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" }, - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "optional": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } - } + "object-path": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz", + "integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==" }, "on-finished": { "version": "2.4.1", @@ -12660,7 +31088,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" } @@ -12682,43 +31110,40 @@ "mimic-fn": "^2.1.0" } }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true - }, "optimism": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.16.1.tgz", - "integrity": "sha512-64i+Uw3otrndfq5kaoGNoY7pvOhSsjFEN4bdEFh80MWVk/dbgJfMv7VFDeCT8LxNAlEVhQmdVEbfE7X2nWNIIg==", - "dev": true, - "requires": { - "@wry/context": "^0.6.0", - "@wry/trie": "^0.3.0" - } - }, - "optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0.tgz", + "integrity": "sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ==", "dev": true, "requires": { - "require-at": "^1.0.6" + "@wry/caches": "^1.0.0", + "@wry/context": "^0.7.0", + "@wry/trie": "^0.4.3", + "tslib": "^2.3.0" + }, + "dependencies": { + "@wry/trie": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.4.3.tgz", + "integrity": "sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==", + "dev": true, + "requires": { + "tslib": "^2.3.0" + } + } } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "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": { @@ -12738,12 +31163,6 @@ "wcwidth": "^1.0.1" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -12753,17 +31172,6 @@ "color-convert": "^2.0.1" } }, - "bl": { - "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", - "readable-stream": "^3.4.0" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -12795,26 +31203,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12826,16 +31214,18 @@ } } }, - "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=", - "dev": true + "otpauth": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/otpauth/-/otpauth-9.2.2.tgz", + "integrity": "sha512-2VcnYRUmq1dNckIfySNYP32ITWp1bvTeAEW0BSCR6G3GBf3a5zb9E+ubY62t3Dma9RjoHlvd7QpmzHfJZRkiNg==", + "requires": { + "jssha": "~3.3.1" + } }, "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true }, "p-each-series": { @@ -12844,15 +31234,6 @@ "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", "dev": true }, - "p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "requires": { - "p-timeout": "^3.1.0" - } - }, "p-filter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", @@ -12870,12 +31251,6 @@ } } }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, "p-is-promise": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", @@ -12883,21 +31258,19 @@ "dev": true }, "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, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.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, + "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==", "requires": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" } }, "p-map": { @@ -12916,24 +31289,15 @@ "dev": true }, "p-retry": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", - "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, "requires": { - "@types/retry": "^0.12.0", + "@types/retry": "0.12.0", "retry": "^0.13.1" } }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -12966,69 +31330,61 @@ "wcwidth": "^1.0.1" } }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" } }, "parse": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/parse/-/parse-3.4.2.tgz", - "integrity": "sha512-Ruehcp/S7eB3A0lDG5eAPvZHa5pABCbUR+lMJL2gUNKJLZNcD9/s3RL255PwI5jTqa+TCJ7MdPqobUplouN1pQ==", - "requires": { - "@babel/runtime": "7.17.9", - "@babel/runtime-corejs3": "7.17.8", - "crypto-js": "4.1.1", - "idb-keyval": "6.0.3", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse/-/parse-5.0.0.tgz", + "integrity": "sha512-6gOARZWiHjmGusbTskhC1qlRn527olMEsdt2LLj9cP2GY3n4VFOwFwV8z/vm2+YfzPfPcv8z7qLih1NzmqzO0g==", + "requires": { + "@babel/runtime-corejs3": "7.23.2", + "crypto-js": "4.2.0", + "idb-keyval": "6.2.1", "react-native-crypto-js": "1.0.0", - "uuid": "3.4.0", - "ws": "7.5.1", + "uuid": "9.0.1", + "ws": "8.16.0", "xmlhttprequest": "1.8.0" }, "dependencies": { - "@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "@babel/runtime-corejs3": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz", - "integrity": "sha512-ZbYSUvoSF6dXZmMl/CYTMOvzIFnbGfv4W3SEHYgMvNsFTeLaF2gkGAF4K2ddmtSK4Emej+0aYcnSC6N5dPCXUQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.2.tgz", + "integrity": "sha512-54cIh74Z1rp4oIjsHjqN+WM4fMyCBYe+LpZ9jWm51CZ1fbH3SkAzQD/3XLoNkjbJ7YEmjobLXyvQrFypRHOrXw==", "requires": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" } }, - "core-js-pure": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.8.tgz", - "integrity": "sha512-bOxbZIy9S5n4OVH63XaLVXZ49QKicjowDx/UELyJ68vxfCRpYsbyh/WNZNfEfAk+ekA8vSjt+gCDpvh672bc3w==" + "crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "optional": true }, "idb-keyval": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.0.3.tgz", - "integrity": "sha512-yh8V7CnE6EQMu9YDwQXhRxwZh4nv+8xm/HV4ZqK4IiYFJBWYGjJuykADJbSP+F/GDXUBwCSSNn/14IpGL81TuA==", - "requires": { - "safari-14-idb-fix": "^3.0.0" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "ws": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.1.tgz", - "integrity": "sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", + "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==" + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" } } }, @@ -13055,37 +31411,20 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "optional": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true, - "optional": 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 + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "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=", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", @@ -13094,9 +31433,9 @@ "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": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" }, "path-type": { "version": "4.0.0", @@ -13107,32 +31446,39 @@ "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, "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==" }, "pg": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz", - "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.5.0", - "pg-pool": "^3.5.2", - "pg-protocol": "^1.5.0", + "pg-cloudflare": "^1.1.1", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", + "pg-protocol": "^1.6.0", "pg-types": "^2.1.0", "pgpass": "1.x" } }, + "pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, "pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" }, "pg-int8": { "version": "1.0.1", @@ -13140,38 +31486,79 @@ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" }, "pg-minify": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz", - "integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg==" + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.3.tgz", + "integrity": "sha512-NoSsPqXxbkD8RIe+peQCqiea4QzXgosdTKY8p7PsbbGsh2F8TifDj/vJxfuR8qJwNYrijdSs7uf0tAe6WOyCsQ==" }, "pg-monitor": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/pg-monitor/-/pg-monitor-1.5.0.tgz", - "integrity": "sha512-Zg5RpoYaz0zyRwAQWKrRxUZgzZ+/r4McMP4vEvg+qE8765SHAB1wHZL58uAjocG4WSK/NLP/zZhUuoyurw4l6Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pg-monitor/-/pg-monitor-2.0.0.tgz", + "integrity": "sha512-UqjhroM701sRrJHhXeF1OwNBGxkN9R0YgkVU8A46wWn3RwK/K7QDylChMoDxo8TmGp86CBP4ZSf+RK9vD8XyVA==", "requires": { "cli-color": "2.0.3" + }, + "dependencies": { + "cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + } } }, "pg-pool": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz", - "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==" + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "requires": {} }, "pg-promise": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.12.0.tgz", - "integrity": "sha512-7uN64iEHrhtRcOaU/AT3925S20JzQJG2nWVK2IUz5SlhB1eNdkXjAYoQtei+5kLJo81mOWcFq7x9J9VRldp0ig==", + "version": "11.5.4", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.5.4.tgz", + "integrity": "sha512-esYSkDt2h6NQOkfotGAm1Ld5OjoITJLpB88Z1PIlcAU/RQ0XQE2PxW0bLJEOMHPGV5iaRnj1Y7ARznXbgN4FNw==", "requires": { - "assert-options": "0.7.0", - "pg": "8.8.0", - "pg-minify": "1.6.2", - "spex": "3.2.0" + "assert-options": "0.8.1", + "pg": "8.11.3", + "pg-minify": "1.6.3", + "spex": "3.3.0" } }, "pg-protocol": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", - "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" }, "pg-types": { "version": "2.2.0", @@ -13194,16 +31581,21 @@ }, "dependencies": { "split2": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", - "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" } } }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pify": { @@ -13215,13 +31607,13 @@ "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -13230,7 +31622,7 @@ "pkg-conf": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", - "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", "dev": true, "requires": { "find-up": "^2.0.0", @@ -13240,7 +31632,7 @@ "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -13249,7 +31641,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -13268,7 +31660,7 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -13277,26 +31669,17 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "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" - } - }, "please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -13311,33 +31694,34 @@ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "optional": true - }, "postcss": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz", - "integrity": "sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "dev": true, "requires": { - "colorette": "^1.2.2", - "nanoid": "^3.1.23", - "source-map-js": "^0.6.2" + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" } }, "postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz", + "integrity": "sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==", "dev": true, "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + }, + "dependencies": { + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } } }, "postgres-array": { @@ -13364,16 +31748,16 @@ } }, "precinct": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/precinct/-/precinct-8.1.0.tgz", - "integrity": "sha512-oeZBR9IdER42Ef6Rz11z1oOUqicsI5J1Qffj6tYghKLhxN2UnHy7uE1axxNr0VZRevPK2HWkROk36uXrbJwHFA==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-8.3.1.tgz", + "integrity": "sha512-pVppfMWLp2wF68rwHqBIpPBYY8Kd12lDhk8LVQzOwqllifVR15qNFyod43YLyFpurKRZQKnE7E4pofAagDOm2Q==", "dev": true, "requires": { "commander": "^2.20.3", - "debug": "^4.3.1", - "detective-amd": "^3.0.1", + "debug": "^4.3.3", + "detective-amd": "^3.1.0", "detective-cjs": "^3.1.1", - "detective-es6": "^2.2.0", + "detective-es6": "^2.2.1", "detective-less": "^1.0.2", "detective-postcss": "^4.0.0", "detective-sass": "^3.0.1", @@ -13384,19 +31768,78 @@ "node-source-walk": "^4.2.0" }, "dependencies": { + "@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 + }, + "@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, + "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", + "tsutils": "^3.21.0" + } + }, + "@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, + "requires": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "ast-module-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-3.0.0.tgz", + "integrity": "sha512-CMxMCOCS+4D+DkOQfuZf+vLrSEmY/7xtORwdxs4wtcC1wVgvk2MqFFTwQCFhvWsI4KPU9lcWXPI8DgRiz+xetQ==", + "dev": true + }, "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==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "detective-amd": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-3.1.2.tgz", + "integrity": "sha512-jffU26dyqJ37JHR/o44La6CxtrDf3Rt9tvd2IbImJYxWKTMdBjctp37qoZ6ZcY80RHg+kzWz4bXn39e4P7cctQ==", + "dev": true, + "requires": { + "ast-module-types": "^3.0.0", + "escodegen": "^2.0.0", + "get-amd-module-type": "^3.0.0", + "node-source-walk": "^4.2.0" + } + }, + "detective-cjs": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-3.1.3.tgz", + "integrity": "sha512-ljs7P0Yj9MK64B7G0eNl0ThWSYjhAaSYy+fQcpzaKalYl/UoQBOzOeLCSFEY1qEBhziZ3w7l46KG/nH+s+L7BQ==", + "dev": true, + "requires": { + "ast-module-types": "^3.0.0", + "node-source-walk": "^4.0.0" + } + }, + "detective-es6": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.2.tgz", + "integrity": "sha512-eZUKCUsbHm8xoeoCM0z6JFwvDfJ5Ww5HANo+jPR7AzkFpW9Mun3t/TqIF2jjeWa2TFbAiGaWESykf2OQp3oeMw==", "dev": true, "requires": { - "ms": "2.1.2" + "node-source-walk": "^4.0.0" } }, "detective-postcss": { @@ -13411,10 +31854,86 @@ "postcss-values-parser": "^2.0.1" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "detective-sass": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-3.0.2.tgz", + "integrity": "sha512-DNVYbaSlmti/eztFGSfBw4nZvwsTaVXEQ4NsT/uFckxhJrNRFUh24d76KzoCC3aarvpZP9m8sC2L1XbLej4F7g==", + "dev": true, + "requires": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^4.0.0" + } + }, + "detective-scss": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-2.0.2.tgz", + "integrity": "sha512-hDWnWh/l0tht/7JQltumpVea/inmkBaanJUcXRB9kEEXVwVUMuZd6z7eusQ6GcBFrfifu3pX/XPyD7StjbAiBg==", + "dev": true, + "requires": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^4.0.0" + } + }, + "detective-stylus": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-1.0.3.tgz", + "integrity": "sha512-4/bfIU5kqjwugymoxLXXLltzQNeQfxGoLm2eIaqtnkWxqbhap9puDVpJPVDx96hnptdERzS5Cy6p9N8/08A69Q==", + "dev": true + }, + "detective-typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-7.0.2.tgz", + "integrity": "sha512-unqovnhxzvkCz3m1/W4QW4qGsvXCU06aU2BAm8tkza+xLnp9SOFnob2QsTxUv5PdnQKfDvWcv9YeOeFckWejwA==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "^4.33.0", + "ast-module-types": "^2.7.1", + "node-source-walk": "^4.2.0", + "typescript": "^3.9.10" + }, + "dependencies": { + "ast-module-types": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-2.7.1.tgz", + "integrity": "sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw==", + "dev": true + } + } + }, + "get-amd-module-type": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-3.0.2.tgz", + "integrity": "sha512-PcuKwB8ouJnKuAPn6Hk3UtdfKoUV3zXRqVEvj8XGIXqjWfgd1j7QGdXy5Z9OdQfzVt1Sk29HVe/P+X74ccOuqw==", + "dev": true, + "requires": { + "ast-module-types": "^3.0.0", + "node-source-walk": "^4.2.2" + } + }, + "node-source-walk": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.3.0.tgz", + "integrity": "sha512-8Q1hXew6ETzqKRAs3jjLioSxNfT1cx74ooiF8RlAONwVMcfq+UdzLC2eB5qcPldUxaE5w3ytLkrmV1TGddhZTA==", + "dev": true, + "requires": { + "@babel/parser": "^7.0.0" + } + }, + "postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", "dev": true } } @@ -13425,16 +31944,9 @@ "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==" }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, "prettier": { "version": "2.0.5", @@ -13442,50 +31954,6 @@ "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "dev": true }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "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==", - "dev": true - } - } - }, "pretty-ms": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", @@ -13498,7 +31966,8 @@ "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==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "process-on-spawn": { "version": "1.0.0", @@ -13509,11 +31978,10 @@ "fromentries": "^1.2.0" } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "process-warning": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==" }, "prop-types": { "version": "15.8.1", @@ -13526,11 +31994,42 @@ "react-is": "^16.13.1" } }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true + "proto3-json-serializer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", + "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", + "optional": true, + "requires": { + "protobufjs": "^7.2.5" + } + }, + "protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "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.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true + } + } }, "proxy-addr": { "version": "2.0.7", @@ -13541,24 +32040,15 @@ "ipaddr.js": "1.9.1" } }, - "ps-node": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ps-node/-/ps-node-0.1.6.tgz", - "integrity": "sha1-mvZ6mdex0BMuUaUDCZ04qNKs4sM=", - "dev": true, - "requires": { - "table-parser": "^0.1.3" - } - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "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==" + "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", @@ -13571,26 +32061,28 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "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", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "quick-lru": { "version": "4.0.1", @@ -13601,7 +32093,7 @@ "quote-unquote": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", - "integrity": "sha1-Z6mncUjv/q+BpNQoQEpxC6qsigs=", + "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", "dev": true }, "range-parser": { @@ -13609,10 +32101,16 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, + "rate-limit-redis": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-3.0.2.tgz", + "integrity": "sha512-4SBK6AzIr9PKkCF4HmSDcJH2O2KKMF3fZEcsbNMXyaL5I9d6X71uOreUldFRiyrRyP+qkQrTxzJ38ZKKN+sScw==", + "requires": {} + }, "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "requires": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -13635,7 +32133,7 @@ "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=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true } } @@ -13706,6 +32204,43 @@ "type-fest": "^0.8.1" }, "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" + } + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -13718,6 +32253,7 @@ "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", @@ -13731,20 +32267,19 @@ "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==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true } } }, "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "optional": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "picomatch": "^2.2.1" } }, "redent": { @@ -13760,39 +32295,23 @@ "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" } }, "redis": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", - "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==", - "requires": { - "denque": "^1.5.0", - "redis-commands": "^1.7.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0" - } - }, - "redis-commands": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", - "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" - }, - "redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" - }, - "redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz", + "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==", "requires": { - "redis-errors": "^1.0.0" + "@redis/bloom": "1.2.0", + "@redis/client": "1.5.14", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.6", + "@redis/search": "1.1.6", + "@redis/time-series": "1.0.5" } }, "regenerate": { @@ -13802,78 +32321,60 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dev": true, "requires": { - "regenerate": "^1.4.0" + "regenerate": "^1.4.2" } }, "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.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, "requires": { "@babel/runtime": "^7.8.4" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" }, "regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" } }, "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==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", + "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", "dev": true, "requires": { - "rc": "^1.2.8" + "rc": "1.2.8" } }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, "regjsparser": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", - "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -13882,41 +32383,33 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true } } }, + "rehackt": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.0.5.tgz", + "integrity": "sha512-BI1rV+miEkaHj8zd2n+gaMgzu/fKz7BGlb4zZ6HAiY9adDmJMkaDcmuXlJFv0eyKUob+oszs3/2gdnXUrzx2Tg==", + "dev": true, + "requires": {} + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, "requires": { "es6-error": "^4.0.1" } }, - "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=", - "dev": true, - "optional": true - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "optional": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "optional": true - }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -13954,6 +32447,11 @@ "mime-types": "^2.1.12" } }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -13961,17 +32459,11 @@ } } }, - "require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true }, "require-main-filename": { "version": "2.0.0", @@ -13979,30 +32471,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "require_optional": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", - "dev": true, - "requires": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" - }, - "dependencies": { - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "requirejs": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", @@ -14020,24 +32488,31 @@ } }, "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", "dev": true, "requires": { - "lodash": "^4.17.14" + "lodash": "^4.17.21" } }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dev": true, "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "resolve-dependency-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz", @@ -14047,23 +32522,21 @@ "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 + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true, - "optional": true + "response-iterator": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/response-iterator/-/response-iterator-0.2.6.tgz", + "integrity": "sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==", + "dev": true }, "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dev": true, "requires": { - "lowercase-keys": "^2.0.0" + "lowercase-keys": "^3.0.0" } }, "restore-cursor": { @@ -14076,45 +32549,39 @@ "signal-exit": "^3.0.2" } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "optional": true - }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, + "retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "optional": true, + "requires": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + } }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } }, - "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 - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -14141,40 +32608,21 @@ "resolved": "https://registry.npmjs.org/safari-14-idb-fix/-/safari-14-idb-fix-3.0.0.tgz", "integrity": "sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==" }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "optional": true, - "requires": { - "ret": "~0.1.10" - } + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "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", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "requires": { - "sparse-bitfield": "^3.0.3" - } - }, "sass-lookup": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-3.0.0.tgz", @@ -14245,10 +32693,10 @@ "yargs": "^16.2.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", "dev": true }, "ansi-styles": { @@ -14260,13 +32708,14 @@ "color-convert": "^2.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "cliui": { @@ -14295,85 +32744,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "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" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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" - } - }, - "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==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-versions": { + "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "dev": true, - "requires": { - "semver-regex": "^3.1.2" - } - }, - "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 - }, - "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 - }, - "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==", - "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==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "marked": { @@ -14382,61 +32756,33 @@ "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", "dev": true }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "marked-terminal": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-4.2.0.tgz", + "integrity": "sha512-DQfNRV9svZf0Dm9Cf5x5xaVJ1+XjxQW6XjFJ5HFkVyK52SDpj5PCBzS5X5r2w9nHr3mlB0T5201UMLue9fmhUw==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "ansi-escapes": "^4.3.1", + "cardinal": "^2.1.1", + "chalk": "^4.1.0", + "cli-table3": "^0.6.0", + "node-emoji": "^1.10.0", + "supports-hyperlinks": "^2.1.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 - }, "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 }, - "semver-regex": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz", - "integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==", - "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==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "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==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "is-number": "^7.0.0" + "has-flag": "^4.0.0" } }, "wrap-ansi": { @@ -14470,19 +32816,13 @@ "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true } } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "requires": { "lru-cache": "^6.0.0" }, @@ -14500,7 +32840,7 @@ "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", "dev": true }, "semver-diff": { @@ -14587,43 +32927,26 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -14631,8 +32954,24 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "showdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", + "dev": true, + "requires": { + "commander": "^9.0.0" + }, + "dependencies": { + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true + } + } }, "side-channel": { "version": "1.0.4", @@ -14645,9 +32984,10 @@ } }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "signale": { "version": "1.4.0", @@ -14663,7 +33003,7 @@ "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -14677,6 +33017,13 @@ "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==" + } } }, "slash": { @@ -14686,162 +33033,46 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } - } - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, - "optional": true, "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true, "requires": { - "is-descriptor": "^0.1.0" + "color-convert": "^2.0.1" } }, - "extend-shallow": { + "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "optional": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "color-name": "~1.1.4" } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } } }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" }, "socks": { "version": "2.7.1", @@ -14852,61 +33083,16 @@ "smart-buffer": "^4.2.0" } }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", - "dev": true, - "requires": { - "sort-keys": "^1.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", - "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "optional": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true, - "optional": true + "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 }, "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" @@ -14915,7 +33101,7 @@ "spawn-error-forwarder": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", - "integrity": "sha1-Gv2Uc46ZmwNG17n8NzvlXgdXcCk=", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", "dev": true }, "spawn-wrap": { @@ -14941,15 +33127,6 @@ "semver": "^6.0.0" } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -14985,15 +33162,15 @@ } }, "spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, "spex": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz", - "integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.3.0.tgz", + "integrity": "sha512-VNiXjFp6R4ldPbVRYbpxlD35yRHceecVXlct1J4/X80KuuPnW2AXMq3sGwhnJOhKkUsOxAT6nRGfGE5pocVw5w==" }, "split": { "version": "1.0.1", @@ -15004,16 +33181,6 @@ "through": "2" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "optional": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, "split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", @@ -15039,13 +33206,13 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -15063,29 +33230,6 @@ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "optional": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "optional": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -15094,18 +33238,57 @@ "stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", "dev": true, "requires": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, + "stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "requires": { + "stubs": "^3.0.0" + } + }, + "stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "optional": true + }, + "stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", + "dev": true, + "requires": { + "any-promise": "^1.1.0" + } + }, "streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" }, + "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==" + } + } + }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", @@ -15119,28 +33302,13 @@ "dev": true }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "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==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "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==" - } + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "stringify-object": { @@ -15152,14 +33320,22 @@ "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", "is-regexp": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true + } } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -15195,17 +33371,19 @@ "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 + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - } + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "optional": true + }, + "stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "optional": true }, "stylus-lookup": { "version": "3.0.2", @@ -15222,21 +33400,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "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 } } }, @@ -15258,9 +33421,10 @@ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, "ws": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==" + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} } } }, @@ -15268,15 +33432,14 @@ "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" } }, "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", @@ -15300,85 +33463,46 @@ } } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", "dev": true }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } } } }, - "table-parser": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/table-parser/-/table-parser-0.1.3.tgz", - "integrity": "sha1-BEHPzhallIFoTCfRtaZ/8VpDx7A=", - "dev": true, - "requires": { - "connected-domain": "^1.0.0" - } - }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true - }, "tar-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", @@ -15406,11 +33530,68 @@ } } }, - "temp": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.4.0.tgz", - "integrity": "sha1-ZxrWPVe+D+nXKUZks/xABjZnimA=", - "dev": true + "teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "optional": true, + "requires": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.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 + }, + "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" + } + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } }, "temp-dir": { "version": "2.0.0", @@ -15450,6 +33631,11 @@ "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-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", @@ -15464,63 +33650,36 @@ "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 + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "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 }, "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "3" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true } } }, - "tildify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", - "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", - "dev": true - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, "timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -15530,20 +33689,6 @@ "next-tick": "1" } }, - "tiny-lru": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-7.0.6.tgz", - "integrity": "sha512-zNYO0Kvgn5rXzWpL0y3RS09sMK67eGaQj9805jlK9G6pSadfriTczzLHFXa/xcW4mIRfmlB9HyQ/+SgL0V1uow==" - }, - "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" - } - }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", @@ -15551,61 +33696,17 @@ "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-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", - "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", - "dev": true - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "optional": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } + "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==" }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "optional": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "toidentifier": { @@ -15620,24 +33721,27 @@ "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" }, "dependencies": { "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" } } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", "dev": true }, "trim-newlines": { @@ -15646,41 +33750,59 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" + }, + "ts-graphviz": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-1.8.2.tgz", + "integrity": "sha512-5YhbFoHmjxa7pgQLkB07MtGnGJ/yhvjmc9uhsnDBEICME6gkPf83SBwLDQqGDoCa3XzUMWLk1AU2Wn1u1naDtA==", + "dev": true + }, + "ts-invariant": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", + "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.2" + "tslib": "^2.1.0" } }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "ts-invariant": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", - "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "requires": { - "tslib": "^1.9.3" + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" }, "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true } } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "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", @@ -15708,7 +33830,7 @@ "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" } @@ -15716,25 +33838,24 @@ "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==" }, "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -15742,12 +33863,6 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, - "type-fest": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", - "dev": true - }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -15767,9 +33882,9 @@ } }, "typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "uc.micro": { @@ -15779,11 +33894,10 @@ "dev": true }, "uglify-js": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", - "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", - "dev": true, - "optional": true + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true }, "unbzip2-stream": { "version": "1.4.3", @@ -15796,61 +33910,48 @@ } }, "underscore": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", - "integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, - "undici": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.9.1.tgz", - "integrity": "sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==" + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true }, "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" } }, "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "dev": true }, "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "optional": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", "dev": true }, "unique-string": { @@ -15869,155 +33970,66 @@ "dev": true }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "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==" }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "optional": true, + "update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "optional": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "optional": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "optional": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "optional": true - } + "escalade": "^3.1.1", + "picocolors": "^1.0.0" } }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", "dev": true }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "optional": true - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "requires": { "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true, - "optional": true - }, "url-join": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "optional": true - }, - "use-sync-external-store": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz", - "integrity": "sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ==", - "dev": true - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, "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==" }, "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": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" - }, - "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==", - "dev": true + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -16030,14 +34042,14 @@ } }, "value-or-promise": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", - "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==" + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.12.tgz", + "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==" }, "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==" }, "vasync": { "version": "2.2.1", @@ -16045,16 +34057,40 @@ "integrity": "sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ==", "requires": { "verror": "1.10.0" + }, + "dependencies": { + "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==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + } } }, "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" + }, + "dependencies": { + "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==" + } } }, "walkdir": { @@ -16066,36 +34102,56 @@ "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, "requires": { "defaults": "^1.0.3" } }, "web-streams-polyfill": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", - "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true }, "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, + "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==" }, "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" } }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -16103,13 +34159,7 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, "wide-align": { @@ -16121,10 +34171,11 @@ } }, "winston": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.1.tgz", - "integrity": "sha512-r+6YAiCR4uI3N8eQNOg8k3P3PqwAm20cLKlzVD9E66Ch39+LZC+VH1UKf9JemQj2B3QoUHfKD7Poewn0Pr3Y1w==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.12.0.tgz", + "integrity": "sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==", "requires": { + "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", @@ -16134,9 +34185,14 @@ "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" + "winston-transport": "^4.7.0" }, "dependencies": { + "@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -16150,20 +34206,20 @@ } }, "winston-daily-rotate-file": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz", - "integrity": "sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-5.0.0.tgz", + "integrity": "sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw==", "requires": { "file-stream-rotator": "^0.6.1", - "object-hash": "^2.0.1", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" + "object-hash": "^3.0.0", + "triple-beam": "^1.4.1", + "winston-transport": "^4.7.0" } }, "winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", "requires": { "logform": "^2.3.2", "readable-stream": "^3.6.0", @@ -16183,15 +34239,14 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, "wrap-ansi": { @@ -16205,12 +34260,6 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16234,48 +34283,13 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true - }, - "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==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "3.0.3", @@ -16290,20 +34304,21 @@ } }, "ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==" + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "requires": {} }, "xmlcreate": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", - "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, "xmlhttprequest": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==" }, "xtend": { "version": "4.0.2", @@ -16346,54 +34361,65 @@ "yargs-parser": "^18.1.2" }, "dependencies": { - "ansi-regex": { + "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/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "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" + } }, - "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==", - "dev": true + "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" + } }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "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": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "p-limit": "^2.2.0" } }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "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": { - "ansi-regex": "^5.0.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } }, "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" - } + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true }, "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, "requires": { "buffer-crc32": "~0.2.3", @@ -16403,8 +34429,7 @@ "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==", - "dev": true + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" }, "zen-observable": { "version": "0.8.15", @@ -16413,9 +34438,9 @@ "dev": true }, "zen-observable-ts": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.3.tgz", - "integrity": "sha512-hc/TGiPkAWpByykMwDcem3SdUgA4We+0Qb36bItSuJC9xD0XVBZoFHYoadAomDSNf64CG8Ydj0Qb8Od8BUWz5g==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", + "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", "dev": true, "requires": { "zen-observable": "0.8.15" diff --git a/package.json b/package.json index 947daa8e6c..c16ff65cb8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "5.4.0", + "version": "7.0.0", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { @@ -13,61 +13,65 @@ "public_html/", "views/", "LICENSE", - "PATENTS", + "NOTICE", "postinstall.js", "README.md" ], - "license": "BSD-3-Clause", + "license": "Apache-2.0", "dependencies": { - "@graphql-yoga/node": "2.6.0", + "@apollo/server": "4.10.1", + "@babel/eslint-parser": "7.21.8", + "@graphql-tools/merge": "8.4.1", + "@graphql-tools/schema": "10.0.3", "@graphql-tools/utils": "8.12.0", - "@graphql-tools/merge": "8.3.6", - "@graphql-tools/schema": "9.0.4", - "@parse/fs-files-adapter": "1.2.2", - "@parse/push-adapter": "4.1.2", + "@parse/fs-files-adapter": "2.0.1", + "@parse/push-adapter": "5.1.1", "bcryptjs": "2.4.3", - "body-parser": "1.20.1", - "commander": "5.1.0", + "body-parser": "1.20.2", + "commander": "12.0.0", "cors": "2.8.5", "deepcopy": "2.1.0", - "express": "4.18.1", - "follow-redirects": "1.15.2", - "graphql": "16.6.0", - "graphql-list-fields": "2.0.2", - "graphql-tag": "2.12.6", + "express": "4.18.2", + "express-rate-limit": "6.11.2", + "follow-redirects": "1.15.6", + "graphql": "16.8.1", + "graphql-list-fields": "2.0.4", "graphql-relay": "0.10.0", + "graphql-tag": "2.12.6", + "graphql-upload": "15.0.2", "intersect": "1.0.1", - "jsonwebtoken": "8.5.1", - "jwks-rsa": "2.1.4", - "ldapjs": "2.3.3", + "jsonwebtoken": "9.0.0", + "jwks-rsa": "3.1.0", + "ldapjs": "3.0.7", "lodash": "4.17.21", - "lru-cache": "7.12.0", + "lru-cache": "10.1.0", "mime": "3.0.0", - "mongodb": "4.10.0", + "mongodb": "5.9.0", "mustache": "4.2.0", - "parse": "3.4.2", - "pg-monitor": "1.5.0", - "pg-promise": "10.12.0", + "otpauth": "9.2.2", + "parse": "5.0.0", + "path-to-regexp": "6.2.1", + "pg-monitor": "2.0.0", + "pg-promise": "11.5.4", "pluralize": "8.0.0", - "redis": "3.1.2", - "semver": "7.3.8", + "rate-limit-redis": "3.0.2", + "redis": "4.6.13", + "semver": "7.6.0", "subscriptions-transport-ws": "0.11.0", "tv4": "1.3.0", - "uuid": "9.0.0", - "winston": "3.8.1", - "winston-daily-rotate-file": "4.7.1", - "ws": "8.9.0" + "uuid": "9.0.1", + "winston": "3.12.0", + "winston-daily-rotate-file": "5.0.0", + "ws": "8.16.0" }, "devDependencies": { - "graphql-tag": "2.12.6", "@actions/core": "1.9.1", - "@apollo/client": "3.6.1", - "@babel/cli": "7.10.0", - "@babel/core": "7.10.0", + "@apollo/client": "3.9.5", + "@babel/cli": "7.23.9", + "@babel/core": "7.24.0", "@babel/plugin-proposal-object-rest-spread": "7.10.0", - "@babel/plugin-transform-flow-strip-types": "7.9.0", - "@babel/preset-env": "7.10.0", - "@parse/minami": "1.0.0", + "@babel/plugin-transform-flow-strip-types": "7.23.3", + "@babel/preset-env": "7.24.0", "@saithodev/semantic-release-backmerge": "2.1.2", "@semantic-release/changelog": "5.0.1", "@semantic-release/commit-analyzer": "8.0.1", @@ -75,28 +79,28 @@ "@semantic-release/github": "7.2.3", "@semantic-release/npm": "7.1.3", "@semantic-release/release-notes-generator": "9.0.3", - "all-node-versions": "8.0.0", - "apollo-upload-client": "16.0.0", - "apollo-utilities": "1.3.4", - "babel-eslint": "10.1.0", - "bcrypt-nodejs": "0.0.3", + "all-node-versions": "11.3.0", + "apollo-upload-client": "17.0.0", + "clean-jsdoc-theme": "4.2.7", "cross-env": "7.0.2", "deep-diff": "1.0.2", - "eslint": "6.8.0", - "eslint-plugin-flowtype": "5.1.3", + "eslint": "8.26.0", + "eslint-plugin-flowtype": "8.0.3", "flow-bin": "0.119.1", - "form-data": "3.0.0", - "husky": "4.3.8", + "form-data": "4.0.0", + "graphql-tag": "2.12.6", + "husky": "9.0.11", "jasmine": "3.5.0", "jasmine-spec-reporter": "7.0.0", - "jsdoc": "3.6.3", + "jsdoc": "4.0.2", "jsdoc-babel": "0.5.0", "lint-staged": "10.2.3", - "madge": "5.0.1", + "madge": "6.1.0", "mock-files-adapter": "file:spec/dependencies/mock-files-adapter", "mock-mail-adapter": "file:spec/dependencies/mock-mail-adapter", - "mongodb-runner": "4.8.1", + "mongodb-runner": "5.4.4", "mongodb-version-list": "1.0.0", + "node-abort-controller": "3.0.1", "node-fetch": "3.2.10", "nyc": "15.1.0", "prettier": "2.0.5", @@ -106,26 +110,26 @@ "scripts": { "ci:check": "node ./ci/ciCheck.js", "ci:checkNodeEngine": "node ./ci/nodeEngineCheck.js", + "ci:definitionsCheck": "node ./ci/definitionsCheck.js", "definitions": "node ./resources/buildConfigDefinitions.js && prettier --write 'src/Options/*.js'", "docs": "jsdoc -c ./jsdoc-conf.json", "lint": "flow && eslint --cache ./", "lint-fix": "eslint --fix --cache ./", "build": "babel src/ -d lib/ --copy-files", "watch": "babel --watch src/ -d lib/ --copy-files", - "test:mongodb:runnerstart": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=$npm_config_dbversion} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner start", - "test:mongodb:testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=$npm_config_dbversion} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 jasmine", + "test:mongodb:runnerstart": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=$npm_config_dbversion} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} mongodb-runner start -t ${MONGODB_TOPOLOGY} --version ${MONGODB_VERSION} -- --port 27017", + "test:mongodb:testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=$npm_config_dbversion} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} TESTING=1 jasmine", "test:mongodb": "npm run test:mongodb:runnerstart --dbversion=$npm_config_dbversion && npm run test:mongodb:testonly --dbversion=$npm_config_dbversion", - "test:mongodb:4.0.28": "npm run test:mongodb --dbversion=4.0.28", "test:mongodb:4.2.19": "npm run test:mongodb --dbversion=4.2.19", "test:mongodb:4.4.13": "npm run test:mongodb --dbversion=4.4.13", "test:mongodb:5.3.2": "npm run test:mongodb --dbversion=5.3.2", "test:mongodb:6.0.2": "npm run test:mongodb --dbversion=6.0.2", - "posttest:mongodb": "mongodb-runner stop", - "pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner start", - "testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 jasmine", + "test:mongodb:7.0.1": "npm run test:mongodb --dbversion=7.0.1", + "pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} mongodb-runner start -t ${MONGODB_TOPOLOGY} --version ${MONGODB_VERSION} -- --port 27017", + "testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} TESTING=1 jasmine", "test": "npm run testonly", - "posttest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner stop", - "coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 nyc jasmine", + "posttest": "cross-env mongodb-runner stop --all", + "coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} TESTING=1 nyc jasmine", "start": "node ./bin/parse-server", "prettier": "prettier --write {src,spec}/{**/*,*}.js", "prepare": "npm run build", @@ -133,7 +137,7 @@ "madge:circular": "node_modules/.bin/madge ./src --circular" }, "engines": { - "node": ">=12.22.10 <19" + "node": ">=18.0.0 <21" }, "bin": { "parse-server": "bin/parse-server" diff --git a/postinstall.js b/postinstall.js index fef1fb31ff..fe1fc96bae 100644 --- a/postinstall.js +++ b/postinstall.js @@ -1,6 +1,6 @@ const pkg = require('./package.json'); -const version = parseFloat(process.version.substr(1)); +const version = parseFloat(process.version.substring(1)); const minimum = parseFloat(pkg.engines.node.match(/\d+/g).join('.')); module.exports = function () { diff --git a/release.config.js b/release.config.js index 2307429e77..67d62c56c6 100644 --- a/release.config.js +++ b/release.config.js @@ -24,7 +24,7 @@ const templates = { async function config() { // Get branch - const branch = ref.split('/').pop(); + const branch = ref.split('/').pop().split('-')[0]; console.log(`Running on branch: ${branch}`); // Set changelog file @@ -40,11 +40,8 @@ async function config() { { name: 'alpha', prerelease: true }, { name: 'beta', prerelease: true }, 'next-major', - // Long-Term-Support branches - // { name: 'release-1', range: '1.x.x', channel: '1.x' }, - // { name: 'release-2', range: '2.x.x', channel: '2.x' }, - // { name: 'release-3', range: '3.x.x', channel: '3.x' }, - // { name: 'release-4', range: '4.x.x', channel: '4.x' }, + // Long-Term-Support branch of previous major version + 'release-6.x.x', ], dryRun: false, debug: true, diff --git a/release_docs.sh b/release_docs.sh index a7bb26324c..a9cc5bf3bc 100755 --- a/release_docs.sh +++ b/release_docs.sh @@ -27,3 +27,8 @@ npm run docs mkdir -p "docs/api/${DEST}" cp -R out/* "docs/api/${DEST}" + +# Copy other resources +RESOURCE_DIR=".github" +mkdir -p "docs/${RESOURCE_DIR}" +cp "./.github/parse-server-logo.png" "docs/${RESOURCE_DIR}/" diff --git a/resources/buildConfigDefinitions.js b/resources/buildConfigDefinitions.js index b41c53f07c..0be6e0085d 100644 --- a/resources/buildConfigDefinitions.js +++ b/resources/buildConfigDefinitions.js @@ -24,31 +24,34 @@ const nestedOptionTypes = [ 'PasswordPolicyOptions', 'SecurityOptions', 'SchemaOptions', + 'LogLevels', ]; /** The prefix of environment variables for nested options. */ const nestedOptionEnvPrefix = { - 'AccountLockoutOptions': 'PARSE_SERVER_ACCOUNT_LOCKOUT_', - 'CustomPagesOptions': 'PARSE_SERVER_CUSTOM_PAGES_', - 'DatabaseOptions': 'PARSE_SERVER_DATABASE_', - 'FileUploadOptions': 'PARSE_SERVER_FILE_UPLOAD_', - 'IdempotencyOptions': 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_', - 'LiveQueryOptions': 'PARSE_SERVER_LIVEQUERY_', - 'LiveQueryServerOptions': 'PARSE_LIVE_QUERY_SERVER_', - 'PagesCustomUrlsOptions': 'PARSE_SERVER_PAGES_CUSTOM_URL_', - 'PagesOptions': 'PARSE_SERVER_PAGES_', - 'PagesRoute': 'PARSE_SERVER_PAGES_ROUTE_', - 'ParseServerOptions': 'PARSE_SERVER_', - 'PasswordPolicyOptions': 'PARSE_SERVER_PASSWORD_POLICY_', - 'SecurityOptions': 'PARSE_SERVER_SECURITY_', - 'SchemaOptions': 'PARSE_SERVER_SCHEMA_', + AccountLockoutOptions: 'PARSE_SERVER_ACCOUNT_LOCKOUT_', + CustomPagesOptions: 'PARSE_SERVER_CUSTOM_PAGES_', + DatabaseOptions: 'PARSE_SERVER_DATABASE_', + FileUploadOptions: 'PARSE_SERVER_FILE_UPLOAD_', + IdempotencyOptions: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_', + LiveQueryOptions: 'PARSE_SERVER_LIVEQUERY_', + LiveQueryServerOptions: 'PARSE_LIVE_QUERY_SERVER_', + PagesCustomUrlsOptions: 'PARSE_SERVER_PAGES_CUSTOM_URL_', + PagesOptions: 'PARSE_SERVER_PAGES_', + PagesRoute: 'PARSE_SERVER_PAGES_ROUTE_', + ParseServerOptions: 'PARSE_SERVER_', + PasswordPolicyOptions: 'PARSE_SERVER_PASSWORD_POLICY_', + SecurityOptions: 'PARSE_SERVER_SECURITY_', + SchemaOptions: 'PARSE_SERVER_SCHEMA_', + LogLevels: 'PARSE_SERVER_LOG_LEVELS_', + RateLimitOptions: 'PARSE_SERVER_RATE_LIMIT_', }; function last(array) { return array[array.length - 1]; } -const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; function toENV(key) { let str = ''; let previousIsUpper = false; @@ -68,13 +71,15 @@ function toENV(key) { } function getCommentValue(comment) { - if (!comment) { return } + if (!comment) { + return; + } return comment.value.trim(); } function getENVPrefix(iface) { if (nestedOptionEnvPrefix[iface.id.name]) { - return nestedOptionEnvPrefix[iface.id.name] + return nestedOptionEnvPrefix[iface.id.name]; } } @@ -86,11 +91,11 @@ function processProperty(property, iface) { if (!firstComment) { return; } - const lines = firstComment.split('\n').map((line) => line.trim()); + const lines = firstComment.split('\n').map(line => line.trim()); let help = ''; let envLine; let defaultLine; - lines.forEach((line) => { + lines.forEach(line => { if (line.indexOf(':ENV:') === 0) { envLine = line; } else if (line.indexOf(':DEFAULT:') === 0) { @@ -103,11 +108,13 @@ function processProperty(property, iface) { if (envLine) { env = envLine.split(' ')[1]; } else { - env = (prefix + toENV(name)); + env = prefix + toENV(name); } let defaultValue; if (defaultLine) { - defaultValue = defaultLine.split(' ')[1]; + const defaultArray = defaultLine.split(' '); + defaultArray.shift(); + defaultValue = defaultArray.join(' '); } let type = property.value.type; let isRequired = true; @@ -123,21 +130,20 @@ function processProperty(property, iface) { defaultValue, types: property.value.types, typeAnnotation: property.value.typeAnnotation, - required: isRequired + required: isRequired, }; } - function doInterface(iface) { return iface.body.properties .sort((a, b) => a.key.name.localeCompare(b.key.name)) - .map((prop) => processProperty(prop, iface)) - .filter((e) => e !== undefined); + .map(prop => processProperty(prop, iface)) + .filter(e => e !== undefined); } function mapperFor(elt, t) { const p = t.identifier('parsers'); - const wrap = (identifier) => t.memberExpression(p, identifier); + const wrap = identifier => t.memberExpression(p, identifier); if (t.isNumberTypeAnnotation(elt)) { return t.callExpression(wrap(t.identifier('numberParser')), [t.stringLiteral(elt.name)]); @@ -155,6 +161,9 @@ function mapperFor(elt, t) { if (type == 'NumberOrBoolean') { return wrap(t.identifier('numberOrBooleanParser')); } + if (type === 'StringOrStringArray') { + return wrap(t.identifier('arrayParser')); + } return wrap(t.identifier('objectParser')); } } @@ -171,27 +180,29 @@ function parseDefaultValue(elt, value, t) { literalValue = t.numericLiteral(parsers.numberOrBoolParser('')(value)); } else if (t.isArrayTypeAnnotation(elt)) { const array = parsers.objectParser(value); - literalValue = t.arrayExpression(array.map((value) => { - if (typeof value == 'string') { - return t.stringLiteral(value); - } else if (typeof value == 'number') { - return t.numericLiteral(value); - } else if (typeof value == 'object') { - const object = parsers.objectParser(value); - const props = Object.entries(object).map(([k, v]) => { - if (typeof v == 'string') { - return t.objectProperty(t.identifier(k), t.stringLiteral(v)); - } else if (typeof v == 'number') { - return t.objectProperty(t.identifier(k), t.numericLiteral(v)); - } else if (typeof v == 'boolean') { - return t.objectProperty(t.identifier(k), t.booleanLiteral(v)); - } - }); - return t.objectExpression(props); - } else { - throw new Error('Unable to parse array'); - } - })); + literalValue = t.arrayExpression( + array.map(value => { + if (typeof value == 'string') { + return t.stringLiteral(value); + } else if (typeof value == 'number') { + return t.numericLiteral(value); + } else if (typeof value == 'object') { + const object = parsers.objectParser(value); + const props = Object.entries(object).map(([k, v]) => { + if (typeof v == 'string') { + return t.objectProperty(t.identifier(k), t.stringLiteral(v)); + } else if (typeof v == 'number') { + return t.objectProperty(t.identifier(k), t.numericLiteral(v)); + } else if (typeof v == 'boolean') { + return t.objectProperty(t.identifier(k), t.booleanLiteral(v)); + } + }); + return t.objectExpression(props); + } else { + throw new Error('Unable to parse array'); + } + }) + ); } else if (t.isAnyTypeAnnotation(elt)) { literalValue = t.arrayExpression([]); } else if (t.isBooleanTypeAnnotation(elt)) { @@ -204,15 +215,16 @@ function parseDefaultValue(elt, value, t) { if (nestedOptionTypes.includes(type)) { const object = parsers.objectParser(value); - const props = Object.keys(object).map((key) => { + const props = Object.keys(object).map(key => { return t.objectProperty(key, object[value]); }); literalValue = t.objectExpression(props); } if (type == 'ProtectedFields') { const prop = t.objectProperty( - t.stringLiteral('_User'), t.objectPattern([ - t.objectProperty(t.stringLiteral('*'), t.arrayExpression([t.stringLiteral('email')])) + t.stringLiteral('_User'), + t.objectPattern([ + t.objectProperty(t.stringLiteral('*'), t.arrayExpression([t.stringLiteral('email')])), ]) ); literalValue = t.objectExpression([prop]); @@ -223,62 +235,81 @@ function parseDefaultValue(elt, value, t) { function inject(t, list) { let comments = ''; - const results = list.map((elt) => { - if (!elt.name) { - return; - } - const props = ['env', 'help'].map((key) => { - if (elt[key]) { - return t.objectProperty(t.stringLiteral(key), t.stringLiteral(elt[key])); + const results = list + .map(elt => { + if (!elt.name) { + return; } - }).filter((e) => e !== undefined); - if (elt.required) { - props.push(t.objectProperty(t.stringLiteral('required'), t.booleanLiteral(true))) - } - const action = mapperFor(elt, t); - if (action) { - props.push(t.objectProperty(t.stringLiteral('action'), action)) - } - if (elt.defaultValue) { - const parsedValue = parseDefaultValue(elt, elt.defaultValue, t); - if (parsedValue) { - props.push(t.objectProperty(t.stringLiteral('default'), parsedValue)); - } else { - throw new Error(`Unable to parse value for ${elt.name} `); + const props = ['env', 'help'] + .map(key => { + if (elt[key]) { + return t.objectProperty(t.stringLiteral(key), t.stringLiteral(elt[key])); + } + }) + .filter(e => e !== undefined); + if (elt.required) { + props.push(t.objectProperty(t.stringLiteral('required'), t.booleanLiteral(true))); } - } - let type = elt.type.replace('TypeAnnotation', ''); - if (type === 'Generic') { - type = elt.typeAnnotation.id.name; - } - if (type === 'Array') { - type = elt.typeAnnotation.elementType.id - ? `${elt.typeAnnotation.elementType.id.name}[]` - : `${elt.typeAnnotation.elementType.type.replace('TypeAnnotation', '')}[]`; - } - if (type === 'NumberOrBoolean') { - type = 'Number|Boolean'; - } - if (type === 'NumberOrString') { - type = 'Number|String'; - } - if (type === 'Adapter') { - const adapterType = elt.typeAnnotation.typeParameters.params[0].id.name; - type = `Adapter<${adapterType}>`; - } - comments += ` * @property {${type}} ${elt.name} ${elt.help}\n`; - const obj = t.objectExpression(props); - return t.objectProperty(t.stringLiteral(elt.name), obj); - }).filter((elt) => { - return elt != undefined; - }); + const action = mapperFor(elt, t); + if (action) { + props.push(t.objectProperty(t.stringLiteral('action'), action)); + } + if (elt.defaultValue) { + let parsedValue = parseDefaultValue(elt, elt.defaultValue, t); + if (!parsedValue) { + for (const type of elt.typeAnnotation.types) { + elt.type = type.type; + parsedValue = parseDefaultValue(elt, elt.defaultValue, t); + if (parsedValue) { + break; + } + } + } + if (parsedValue) { + props.push(t.objectProperty(t.stringLiteral('default'), parsedValue)); + } else { + throw new Error(`Unable to parse value for ${elt.name} `); + } + } + let type = elt.type.replace('TypeAnnotation', ''); + if (type === 'Generic') { + type = elt.typeAnnotation.id.name; + } + if (type === 'Array') { + type = elt.typeAnnotation.elementType.id + ? `${elt.typeAnnotation.elementType.id.name}[]` + : `${elt.typeAnnotation.elementType.type.replace('TypeAnnotation', '')}[]`; + } + if (type === 'NumberOrBoolean') { + type = 'Number|Boolean'; + } + if (type === 'NumberOrString') { + type = 'Number|String'; + } + if (type === 'Adapter') { + const adapterType = elt.typeAnnotation.typeParameters.params[0].id.name; + type = `Adapter<${adapterType}>`; + } + if (type === 'StringOrStringArray') { + type = 'String|String[]'; + } + comments += ` * @property {${type}} ${elt.name} ${elt.help}\n`; + const obj = t.objectExpression(props); + return t.objectProperty(t.stringLiteral(elt.name), obj); + }) + .filter(elt => { + return elt != undefined; + }); return { results, comments }; } const makeRequire = function (variableName, module, t) { - const decl = t.variableDeclarator(t.identifier(variableName), t.callExpression(t.identifier('require'), [t.stringLiteral(module)])); - return t.variableDeclaration('var', [decl]) -} + const decl = t.variableDeclarator( + t.identifier(variableName), + t.callExpression(t.identifier('require'), [t.stringLiteral(module)]) + ); + return t.variableDeclaration('var', [decl]); +}; let docs = ``; const plugin = function (babel) { const t = babel.types; @@ -294,27 +325,34 @@ const plugin = function (babel) { }, ExportDeclaration: function (path) { // Export declaration on an interface - if (path.node && path.node.declaration && path.node.declaration.type == 'InterfaceDeclaration') { + if ( + path.node && + path.node.declaration && + path.node.declaration.type == 'InterfaceDeclaration' + ) { const { results, comments } = inject(t, doInterface(path.node.declaration)); const id = path.node.declaration.id.name; const exports = t.memberExpression(moduleExports, t.identifier(id)); docs += `/**\n * @interface ${id}\n${comments} */\n\n`; - path.replaceWith( - t.assignmentExpression('=', exports, t.objectExpression(results)) - ) + path.replaceWith(t.assignmentExpression('=', exports, t.objectExpression(results))); } - } - } - } + }, + }, + }; }; const auxiliaryCommentBefore = ` **** GENERATED CODE **** This code has been generated by resources/buildConfigDefinitions.js Do not edit manually, but update Options/index.js -` +`; -const babel = require("@babel/core"); -const res = babel.transformFileSync('./src/Options/index.js', { plugins: [plugin, '@babel/transform-flow-strip-types'], babelrc: false, auxiliaryCommentBefore, sourceMaps: false }); +const babel = require('@babel/core'); +const res = babel.transformFileSync('./src/Options/index.js', { + plugins: [plugin, '@babel/transform-flow-strip-types'], + babelrc: false, + auxiliaryCommentBefore, + sourceMaps: false, +}); require('fs').writeFileSync('./src/Options/Definitions.js', res.code + '\n'); require('fs').writeFileSync('./src/Options/docs.js', docs); diff --git a/spec/.babelrc b/spec/.babelrc index a611705cd0..abfceb0843 100644 --- a/spec/.babelrc +++ b/spec/.babelrc @@ -1,11 +1,11 @@ { "plugins": [ - "transform-object-rest-spread" + "@babel/plugin-proposal-object-rest-spread" ], "presets": [ - ["env", { + ["@babel/preset-env", { "targets": { - "node": "8" + "node": "14" } }] ], diff --git a/spec/.eslintrc.json b/spec/.eslintrc.json index aa4a8fcdcb..cb61d2fd6c 100644 --- a/spec/.eslintrc.json +++ b/spec/.eslintrc.json @@ -15,6 +15,7 @@ "equal": true, "expectAsync": true, "notEqual": true, + "it_id": true, "it_only_db": true, "it_only_mongodb_version": true, "it_only_postgres_version": true, @@ -27,6 +28,7 @@ "fit_exclude_node_version": true, "it_exclude_dbs": true, "describe_only_db": true, + "fdescribe_only_db": true, "describe_only": true, "on_db": true, "defaultConfiguration": true, @@ -34,7 +36,8 @@ "jequal": true, "create": true, "arrayContains": true, - "databaseAdapter": true + "databaseAdapter": true, + "databaseURI": true }, "rules": { "no-console": [0], diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 4d038562bb..96aedcc313 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -1,11 +1,10 @@ const AggregateRouter = require('../lib/Routers/AggregateRouter').AggregateRouter; describe('AggregateRouter', () => { - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Array', () => { const body = [ { - group: { objectId: {} }, + $group: { _id: {} }, }, ]; const expected = [{ $group: { _id: {} } }]; @@ -13,22 +12,20 @@ describe('AggregateRouter', () => { expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Object', () => { const body = { - group: { objectId: {} }, + $group: { _id: {} }, }; const expected = [{ $group: { _id: {} } }]; const result = AggregateRouter.getPipeline(body); expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Pipeline Operator (Array)', () => { const body = { pipeline: [ { - group: { objectId: {} }, + $group: { _id: {} }, }, ], }; @@ -37,11 +34,10 @@ describe('AggregateRouter', () => { expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Pipeline Operator (Object)', () => { const body = { pipeline: { - group: { objectId: {} }, + $group: { _id: {} }, }, }; const expected = [{ $group: { _id: {} } }]; @@ -49,43 +45,42 @@ describe('AggregateRouter', () => { expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline fails multiple keys in Array stage ', () => { const body = [ { - group: { objectId: {} }, - match: { name: 'Test' }, + $group: { _id: {} }, + $match: { name: 'Test' }, }, ]; - try { - AggregateRouter.getPipeline(body); - } catch (e) { - expect(e.message).toBe('Pipeline stages should only have one key found group, match'); - } + expect(() => AggregateRouter.getPipeline(body)).toThrow( + new Parse.Error( + Parse.Error.INVALID_QUERY, + 'Pipeline stages should only have one key but found $group, $match.' + ) + ); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline fails multiple keys in Pipeline Operator Array stage ', () => { const body = { pipeline: [ { - group: { objectId: {} }, - match: { name: 'Test' }, + $group: { _id: {} }, + $match: { name: 'Test' }, }, ], }; - try { - AggregateRouter.getPipeline(body); - } catch (e) { - expect(e.message).toBe('Pipeline stages should only have one key found group, match'); - } + expect(() => AggregateRouter.getPipeline(body)).toThrow( + new Parse.Error( + Parse.Error.INVALID_QUERY, + 'Pipeline stages should only have one key but found $group, $match.' + ) + ); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get search pipeline from Pipeline Operator (Array)', () => { const body = { pipeline: { - search: {}, + $search: {}, }, }; const expected = [{ $search: {} }]; @@ -105,7 +100,7 @@ describe('AggregateRouter', () => { it('support nested stage names starting with `$`', () => { const body = [ { - lookup: { + $lookup: { from: 'ACollection', let: { id: '_id' }, as: 'results', @@ -145,11 +140,11 @@ describe('AggregateRouter', () => { it('support the use of `_id` in stages', () => { const body = [ - { match: { _id: 'randomId' } }, - { sort: { _id: -1 } }, - { addFields: { _id: 1 } }, - { group: { _id: {} } }, - { project: { _id: 0 } }, + { $match: { _id: 'randomId' } }, + { $sort: { _id: -1 } }, + { $addFields: { _id: 1 } }, + { $group: { _id: {} } }, + { $project: { _id: 0 } }, ]; const expected = [ { $match: { _id: 'randomId' } }, @@ -161,4 +156,19 @@ describe('AggregateRouter', () => { const result = AggregateRouter.getPipeline(body); expect(result).toEqual(expected); }); + + it('should throw with invalid stage', () => { + expect(() => AggregateRouter.getPipeline([{ foo: 'bar' }])).toThrow( + new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage 'foo'.`) + ); + }); + + it('should throw with invalid group', () => { + expect(() => AggregateRouter.getPipeline([{ $group: { objectId: 'bar' } }])).toThrow( + new Parse.Error( + Parse.Error.INVALID_QUERY, + `Cannot use 'objectId' in aggregation stage $group.` + ) + ); + }); }); diff --git a/spec/AudienceRouter.spec.js b/spec/AudienceRouter.spec.js index 9f0f77896a..f2302d32f7 100644 --- a/spec/AudienceRouter.spec.js +++ b/spec/AudienceRouter.spec.js @@ -339,11 +339,12 @@ describe('AudiencesRouter', () => { ) .then(result => { expect(result).toBeTruthy(); + database .collection('test__Audience') .find({ _id: audience.objectId }) - .toArray((error, rows) => { - expect(error).toEqual(undefined); + .toArray() + .then(rows => { expect(rows[0]['times_used']).toEqual(1); expect(rows[0]['_last_used']).toEqual(now); Parse._request( @@ -362,6 +363,9 @@ describe('AudiencesRouter', () => { .catch(error => { done.fail(error); }); + }) + .catch(error => { + done.fail(error); }); }); }); diff --git a/spec/Auth.spec.js b/spec/Auth.spec.js index 5ed6bfe941..632623a871 100644 --- a/spec/Auth.spec.js +++ b/spec/Auth.spec.js @@ -81,17 +81,35 @@ describe('Auth', () => { .then(roles => expect(roles).toEqual([])) .then(() => done()); }); + }); - it('should properly handle bcrypt upgrade', done => { - const bcryptOriginal = require('bcrypt-nodejs'); - const bcryptNew = require('bcryptjs'); - bcryptOriginal.hash('my1Long:password', null, null, function (err, res) { - bcryptNew.compare('my1Long:password', res, function (err, res) { - expect(res).toBeTruthy(); - done(); - }); - }); + it('can use extendSessionOnUse', async () => { + await reconfigureServer({ + extendSessionOnUse: true, + }); + + const user = new Parse.User(); + await user.signUp({ + username: 'hello', + password: 'password', }); + const session = await new Parse.Query(Parse.Session).first(); + const updatedAt = new Date('2010'); + const expiry = new Date(); + expiry.setHours(expiry.getHours() + 1); + + await Parse.Server.database.update( + '_Session', + { objectId: session.id }, + { + expiresAt: { __type: 'Date', iso: expiry.toISOString() }, + updatedAt: updatedAt.toISOString(), + } + ); + await session.fetch(); + await new Promise(resolve => setTimeout(resolve, 1000)); + await session.fetch(); + expect(session.get('expiresAt') > expiry).toBeTrue(); }); it('should load auth without a config', async () => { diff --git a/spec/AuthenticationAdapters.spec.js b/spec/AuthenticationAdapters.spec.js index bcd3d57cf8..c6834dcf45 100644 --- a/spec/AuthenticationAdapters.spec.js +++ b/spec/AuthenticationAdapters.spec.js @@ -256,6 +256,49 @@ describe('AuthenticationProviders', function () { .catch(done.fail); }); + it('should support loginWith with session token and with/without mutated authData', async () => { + const fakeAuthProvider = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + }; + const payload = { authData: { id: 'user1', token: 'fakeToken' } }; + const payload2 = { authData: { id: 'user1', token: 'fakeToken2' } }; + await reconfigureServer({ auth: { fakeAuthProvider } }); + const user = await Parse.User.logInWith('fakeAuthProvider', payload); + const user2 = await Parse.User.logInWith('fakeAuthProvider', payload, { + sessionToken: user.getSessionToken(), + }); + const user3 = await Parse.User.logInWith('fakeAuthProvider', payload2, { + sessionToken: user2.getSessionToken(), + }); + expect(user.id).toEqual(user2.id); + expect(user.id).toEqual(user3.id); + }); + + it('should support sync/async validateAppId', async () => { + const syncProvider = { + validateAppId: () => true, + appIds: 'test', + validateAuthData: () => Promise.resolve(), + }; + const asyncProvider = { + appIds: 'test', + validateAppId: () => Promise.resolve(true), + validateAuthData: () => Promise.resolve(), + }; + const payload = { authData: { id: 'user1', token: 'fakeToken' } }; + const syncSpy = spyOn(syncProvider, 'validateAppId'); + const asyncSpy = spyOn(asyncProvider, 'validateAppId'); + + await reconfigureServer({ auth: { asyncProvider, syncProvider } }); + const user = await Parse.User.logInWith('asyncProvider', payload); + const user2 = await Parse.User.logInWith('syncProvider', payload); + expect(user.getSessionToken()).toBeDefined(); + expect(user2.getSessionToken()).toBeDefined(); + expect(syncSpy).toHaveBeenCalledTimes(1); + expect(asyncSpy).toHaveBeenCalledTimes(1); + }); + it('unlink and link with custom provider', async () => { const provider = getMockMyOauthProvider(); Parse.User._registerAuthenticationProvider(provider); @@ -339,10 +382,10 @@ describe('AuthenticationProviders', function () { }); validateAuthenticationHandler(authenticationHandler); - const validator = authenticationHandler.getValidatorForProvider('customAuthentication'); + const { validator } = authenticationHandler.getValidatorForProvider('customAuthentication'); validateValidator(validator); - validator(validAuthData).then( + validator(validAuthData, {}, {}).then( () => { expect(authDataSpy).toHaveBeenCalled(); // AppIds are not provided in the adapter, should not be called @@ -362,12 +405,15 @@ describe('AuthenticationProviders', function () { }); validateAuthenticationHandler(authenticationHandler); - const validator = authenticationHandler.getValidatorForProvider('customAuthentication'); + const { validator } = authenticationHandler.getValidatorForProvider('customAuthentication'); validateValidator(validator); - - validator({ - token: 'my-token', - }).then( + validator( + { + token: 'my-token', + }, + {}, + {} + ).then( () => { done(); }, @@ -387,12 +433,16 @@ describe('AuthenticationProviders', function () { }); validateAuthenticationHandler(authenticationHandler); - const validator = authenticationHandler.getValidatorForProvider('customAuthentication'); + const { validator } = authenticationHandler.getValidatorForProvider('customAuthentication'); validateValidator(validator); - validator({ - token: 'valid-token', - }).then( + validator( + { + token: 'valid-token', + }, + {}, + {} + ).then( () => { done(); }, @@ -539,18 +589,6 @@ describe('AuthenticationProviders', function () { new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.') ); }); - - it('can depreciate', async () => { - const Deprecator = require('../lib/Deprecator/Deprecator'); - const spy = spyOn(Deprecator, 'logRuntimeDeprecation').and.callFake(() => {}); - const provider = getMockMyOauthProvider(); - Parse.User._registerAuthenticationProvider(provider); - await Parse.User._logInWith('myoauth'); - expect(spy).toHaveBeenCalledWith({ - usage: 'auth.myoauth', - solution: 'auth.myoauth.enabled: true', - }); - }); }); describe('instagram auth adapter', () => { @@ -596,6 +634,7 @@ describe('instagram auth adapter', () => { describe('google auth adapter', () => { const google = require('../lib/Adapters/Auth/google'); const jwt = require('jsonwebtoken'); + const authUtils = require('../lib/Adapters/Auth/utils'); it('should throw error with missing id_token', async () => { try { @@ -618,7 +657,7 @@ describe('google auth adapter', () => { // it('should throw error if public key used to encode token is not available', async () => { // const fakeDecodedToken = { header: { kid: '789', alg: 'RS256' } }; // try { - // spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + // spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); // await google.validateAuthData({ id: 'the_user_id', id_token: 'the_token' }, {}); // fail(); @@ -637,7 +676,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await google.validateAuthData( @@ -653,7 +692,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -677,7 +716,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -699,7 +738,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -1401,7 +1440,7 @@ describe('oauth2 auth adapter', () => { describe('apple signin auth adapter', () => { const apple = require('../lib/Adapters/Auth/apple'); const jwt = require('jsonwebtoken'); - const util = require('util'); + const authUtils = require('../lib/Adapters/Auth/utils'); it('(using client id as string) should throw error with missing id_token', async () => { try { @@ -1436,7 +1475,7 @@ describe('apple signin auth adapter', () => { it('should throw error if public key used to encode token is not available', async () => { const fakeDecodedToken = { header: { kid: '789', alg: 'RS256' } }; try { - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); await apple.validateAuthData( { id: 'the_user_id', token: 'the_token' }, @@ -1458,12 +1497,10 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); const result = await apple.validateAuthData( { id: 'the_user_id', token: 'the_token' }, @@ -1475,11 +1512,9 @@ describe('apple signin auth adapter', () => { it('should not verify invalid id_token', async () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); try { await apple.validateAuthData( @@ -1512,11 +1547,9 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await apple.validateAuthData( @@ -1534,11 +1567,9 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await apple.validateAuthData( @@ -1556,11 +1587,9 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await apple.validateAuthData( @@ -1576,11 +1605,9 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -1604,11 +1631,9 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -1633,11 +1658,9 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -1705,11 +1728,9 @@ describe('apple signin auth adapter', () => { sub: 'a_different_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -1971,7 +1992,7 @@ describe('microsoft graph auth adapter', () => { describe('facebook limited auth adapter', () => { const facebook = require('../lib/Adapters/Auth/facebook'); const jwt = require('jsonwebtoken'); - const util = require('util'); + const authUtils = require('../lib/Adapters/Auth/utils'); // TODO: figure out a way to run this test alongside facebook classic tests xit('(using client id as string) should throw error with missing id_token', async () => { @@ -2010,7 +2031,7 @@ describe('facebook limited auth adapter', () => { header: { kid: '789', alg: 'RS256' }, }; try { - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); await facebook.validateAuthData( { id: 'the_user_id', token: 'the_token' }, @@ -2031,18 +2052,11 @@ describe('facebook limited auth adapter', () => { exp: Date.now(), sub: 'the_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); const result = await facebook.validateAuthData( { id: 'the_user_id', token: 'the_token' }, @@ -2053,17 +2067,10 @@ describe('facebook limited auth adapter', () => { }); it('should not verify invalid id_token', async () => { - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); try { await facebook.validateAuthData( @@ -2095,17 +2102,10 @@ describe('facebook limited auth adapter', () => { exp: Date.now(), sub: 'the_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await facebook.validateAuthData( @@ -2122,17 +2122,10 @@ describe('facebook limited auth adapter', () => { exp: Date.now(), sub: 'the_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await facebook.validateAuthData( @@ -2149,17 +2142,10 @@ describe('facebook limited auth adapter', () => { exp: Date.now(), sub: 'the_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await facebook.validateAuthData( @@ -2174,17 +2160,10 @@ describe('facebook limited auth adapter', () => { iss: 'https://not.facebook.com', sub: 'the_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -2207,17 +2186,10 @@ describe('facebook limited auth adapter', () => { iss: 'https://not.facebook.com', sub: 'the_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -2241,17 +2213,10 @@ describe('facebook limited auth adapter', () => { iss: 'https://not.facebook.com', sub: 'the_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -2327,17 +2292,10 @@ describe('facebook limited auth adapter', () => { aud: 'invalid_client_id', sub: 'a_different_user_id', }; - const fakeDecodedToken = { - header: { kid: '123', alg: 'RS256' }, - }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); - const fakeGetSigningKeyAsyncFunction = () => { - return { - kid: '123', - rsaPublicKey: 'the_rsa_public_key', - }; - }; - spyOn(util, 'promisify').and.callFake(() => fakeGetSigningKeyAsyncFunction); + const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; + const fakeSigningKey = { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getSigningKey').and.resolveTo(fakeSigningKey); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -2351,3 +2309,342 @@ describe('facebook limited auth adapter', () => { } }); }); + +describe('OTP TOTP auth adatper', () => { + const headers = { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + beforeEach(async () => { + await reconfigureServer({ + auth: { + mfa: { + enabled: true, + options: ['TOTP'], + algorithm: 'SHA1', + digits: 6, + period: 30, + }, + }, + }); + }); + + it('can enroll', async () => { + const user = await Parse.User.signUp('username', 'password'); + const OTPAuth = require('otpauth'); + const secret = new OTPAuth.Secret(); + const totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret, + }); + const token = totp.generate(); + await user.save( + { authData: { mfa: { secret: secret.base32, token } } }, + { sessionToken: user.getSessionToken() } + ); + const response = user.get('authDataResponse'); + expect(response.mfa).toBeDefined(); + expect(response.mfa.recovery).toBeDefined(); + expect(response.mfa.recovery.split(',').length).toEqual(2); + await user.fetch(); + expect(user.get('authData').mfa).toEqual({ status: 'enabled' }); + }); + + it('can login with valid token', async () => { + const user = await Parse.User.signUp('username', 'password'); + const OTPAuth = require('otpauth'); + const secret = new OTPAuth.Secret(); + const totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret, + }); + const token = totp.generate(); + await user.save( + { authData: { mfa: { secret: secret.base32, token } } }, + { sessionToken: user.getSessionToken() } + ); + const response = await request({ + headers, + method: 'POST', + url: 'http://localhost:8378/1/login', + body: JSON.stringify({ + username: 'username', + password: 'password', + authData: { + mfa: { + token: totp.generate(), + }, + }, + }), + }).then(res => res.data); + expect(response.objectId).toEqual(user.id); + expect(response.sessionToken).toBeDefined(); + expect(response.authData).toEqual({ mfa: { status: 'enabled' } }); + expect(Object.keys(response).sort()).toEqual( + [ + 'objectId', + 'username', + 'createdAt', + 'updatedAt', + 'authData', + 'ACL', + 'sessionToken', + 'authDataResponse', + ].sort() + ); + }); + + it('can change OTP with valid token', async () => { + const user = await Parse.User.signUp('username', 'password'); + const OTPAuth = require('otpauth'); + const secret = new OTPAuth.Secret(); + const totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret, + }); + const token = totp.generate(); + await user.save( + { authData: { mfa: { secret: secret.base32, token } } }, + { sessionToken: user.getSessionToken() } + ); + + const new_secret = new OTPAuth.Secret(); + const new_totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret: new_secret, + }); + const new_token = new_totp.generate(); + await user.save( + { + authData: { mfa: { secret: new_secret.base32, token: new_token, old: totp.generate() } }, + }, + { sessionToken: user.getSessionToken() } + ); + await user.fetch({ useMasterKey: true }); + expect(user.get('authData').mfa.secret).toEqual(new_secret.base32); + }); + + it('cannot change OTP with invalid token', async () => { + const user = await Parse.User.signUp('username', 'password'); + const OTPAuth = require('otpauth'); + const secret = new OTPAuth.Secret(); + const totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret, + }); + const token = totp.generate(); + await user.save( + { authData: { mfa: { secret: secret.base32, token } } }, + { sessionToken: user.getSessionToken() } + ); + + const new_secret = new OTPAuth.Secret(); + const new_totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret: new_secret, + }); + const new_token = new_totp.generate(); + await expectAsync( + user.save( + { + authData: { mfa: { secret: new_secret.base32, token: new_token, old: '123' } }, + }, + { sessionToken: user.getSessionToken() } + ) + ).toBeRejectedWith(new Parse.Error(Parse.Error.OTHER_CAUSE, 'Invalid MFA token')); + await user.fetch({ useMasterKey: true }); + expect(user.get('authData').mfa.secret).toEqual(secret.base32); + }); + + it('future logins require TOTP token', async () => { + const user = await Parse.User.signUp('username', 'password'); + const OTPAuth = require('otpauth'); + const secret = new OTPAuth.Secret(); + const totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret, + }); + const token = totp.generate(); + await user.save( + { authData: { mfa: { secret: secret.base32, token } } }, + { sessionToken: user.getSessionToken() } + ); + await expectAsync(Parse.User.logIn('username', 'password')).toBeRejectedWith( + new Parse.Error(Parse.Error.OTHER_CAUSE, 'Missing additional authData mfa') + ); + }); + + it('future logins reject incorrect TOTP token', async () => { + const user = await Parse.User.signUp('username', 'password'); + const OTPAuth = require('otpauth'); + const secret = new OTPAuth.Secret(); + const totp = new OTPAuth.TOTP({ + algorithm: 'SHA1', + digits: 6, + period: 30, + secret, + }); + const token = totp.generate(); + await user.save( + { authData: { mfa: { secret: secret.base32, token } } }, + { sessionToken: user.getSessionToken() } + ); + await expectAsync( + request({ + headers, + method: 'POST', + url: 'http://localhost:8378/1/login', + body: JSON.stringify({ + username: 'username', + password: 'password', + authData: { + mfa: { + token: 'abcd', + }, + }, + }), + }).catch(e => { + throw e.data; + }) + ).toBeRejectedWith({ code: Parse.Error.SCRIPT_FAILED, error: 'Invalid MFA token' }); + }); +}); + +describe('OTP SMS auth adatper', () => { + const headers = { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + let code; + let mobile; + const mfa = { + enabled: true, + options: ['SMS'], + sendSMS(smsCode, number) { + expect(smsCode).toBeDefined(); + expect(number).toBeDefined(); + expect(smsCode.length).toEqual(6); + code = smsCode; + mobile = number; + }, + digits: 6, + period: 30, + }; + beforeEach(async () => { + code = ''; + mobile = ''; + await reconfigureServer({ + auth: { + mfa, + }, + }); + }); + + it('can enroll', async () => { + const user = await Parse.User.signUp('username', 'password'); + const sessionToken = user.getSessionToken(); + const spy = spyOn(mfa, 'sendSMS').and.callThrough(); + await user.save({ authData: { mfa: { mobile: '+11111111111' } } }, { sessionToken }); + await user.fetch({ sessionToken }); + expect(user.get('authData')).toEqual({ mfa: { status: 'disabled' } }); + expect(spy).toHaveBeenCalledWith(code, '+11111111111'); + await user.fetch({ useMasterKey: true }); + const authData = user.get('authData').mfa?.pending; + expect(authData).toBeDefined(); + expect(authData['+11111111111']).toBeDefined(); + expect(Object.keys(authData['+11111111111'])).toEqual(['token', 'expiry']); + + await user.save({ authData: { mfa: { mobile, token: code } } }, { sessionToken }); + await user.fetch({ sessionToken }); + expect(user.get('authData')).toEqual({ mfa: { status: 'enabled' } }); + }); + + it('future logins require SMS code', async () => { + const user = await Parse.User.signUp('username', 'password'); + const spy = spyOn(mfa, 'sendSMS').and.callThrough(); + await user.save( + { authData: { mfa: { mobile: '+11111111111' } } }, + { sessionToken: user.getSessionToken() } + ); + + await user.save( + { authData: { mfa: { mobile, token: code } } }, + { sessionToken: user.getSessionToken() } + ); + + spy.calls.reset(); + + await expectAsync(Parse.User.logIn('username', 'password')).toBeRejectedWith( + new Parse.Error(Parse.Error.OTHER_CAUSE, 'Missing additional authData mfa') + ); + const res = await request({ + headers, + method: 'POST', + url: 'http://localhost:8378/1/login', + body: JSON.stringify({ + username: 'username', + password: 'password', + authData: { + mfa: { + token: 'request', + }, + }, + }), + }).catch(e => e.data); + expect(res).toEqual({ code: Parse.Error.SCRIPT_FAILED, error: 'Please enter the token' }); + expect(spy).toHaveBeenCalledWith(code, '+11111111111'); + const response = await request({ + headers, + method: 'POST', + url: 'http://localhost:8378/1/login', + body: JSON.stringify({ + username: 'username', + password: 'password', + authData: { + mfa: { + token: code, + }, + }, + }), + }).then(res => res.data); + expect(response.objectId).toEqual(user.id); + expect(response.sessionToken).toBeDefined(); + expect(response.authData).toEqual({ mfa: { status: 'enabled' } }); + expect(Object.keys(response).sort()).toEqual( + [ + 'objectId', + 'username', + 'createdAt', + 'updatedAt', + 'authData', + 'ACL', + 'sessionToken', + 'authDataResponse', + ].sort() + ); + }); + + it('partially enrolled users can still login', async () => { + const user = await Parse.User.signUp('username', 'password'); + await user.save({ authData: { mfa: { mobile: '+11111111111' } } }); + const spy = spyOn(mfa, 'sendSMS').and.callThrough(); + await Parse.User.logIn('username', 'password'); + expect(spy).not.toHaveBeenCalled(); + }); +}); diff --git a/spec/AuthenticationAdaptersV2.spec.js b/spec/AuthenticationAdaptersV2.spec.js new file mode 100644 index 0000000000..aaa172ea66 --- /dev/null +++ b/spec/AuthenticationAdaptersV2.spec.js @@ -0,0 +1,1288 @@ +const request = require('../lib/request'); +const Auth = require('../lib/Auth'); +const requestWithExpectedError = async params => { + try { + return await request(params); + } catch (e) { + throw new Error(e.data.error); + } +}; +describe('Auth Adapter features', () => { + const baseAdapter = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + }; + const baseAdapter2 = { + validateAppId: appIds => (appIds[0] === 'test' ? Promise.resolve() : Promise.reject()), + validateAuthData: () => Promise.resolve(), + appIds: ['test'], + options: { anOption: true }, + }; + + const doNotSaveAdapter = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve({ doNotSave: true }), + }; + + const additionalAdapter = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + policy: 'additional', + }; + + const soloAdapter = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + policy: 'solo', + }; + + const challengeAdapter = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + challenge: () => Promise.resolve({ token: 'test' }), + options: { + anOption: true, + }, + }; + + const modernAdapter = { + validateAppId: () => Promise.resolve(), + validateSetUp: () => Promise.resolve(), + validateUpdate: () => Promise.resolve(), + validateLogin: () => Promise.resolve(), + }; + + const modernAdapter2 = { + validateAppId: () => Promise.resolve(), + validateSetUp: () => Promise.resolve(), + validateUpdate: () => Promise.resolve(), + validateLogin: () => Promise.resolve(), + }; + + const modernAdapter3 = { + validateAppId: () => Promise.resolve(), + validateSetUp: () => Promise.resolve(), + validateUpdate: () => Promise.resolve(), + validateLogin: () => Promise.resolve(), + validateOptions: () => Promise.resolve(), + afterFind() { + return { + foo: 'bar', + }; + }, + }; + + const wrongAdapter = { + validateAppId: () => Promise.resolve(), + }; + + const headers = { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + + it('should ensure no duplicate auth data id after before save', async () => { + await reconfigureServer({ + auth: { baseAdapter }, + cloud: () => { + Parse.Cloud.beforeSave('_User', async request => { + request.object.set('authData', { baseAdapter: { id: 'test' } }); + }); + }, + }); + + const user = new Parse.User(); + await user.save({ authData: { baseAdapter: { id: 'another' } } }); + await user.fetch({ useMasterKey: true }); + expect(user.get('authData')).toEqual({ baseAdapter: { id: 'test' } }); + + const user2 = new Parse.User(); + await expectAsync( + user2.save({ authData: { baseAdapter: { id: 'another' } } }) + ).toBeRejectedWithError('this auth is already used'); + }); + + it('should ensure no duplicate auth data id after before save in case of more than one result', async () => { + await reconfigureServer({ + auth: { baseAdapter }, + cloud: () => { + Parse.Cloud.beforeSave('_User', async request => { + request.object.set('authData', { baseAdapter: { id: 'test' } }); + }); + }, + }); + + const user = new Parse.User(); + await user.save({ authData: { baseAdapter: { id: 'another' } } }); + await user.fetch({ useMasterKey: true }); + expect(user.get('authData')).toEqual({ baseAdapter: { id: 'test' } }); + + let i = 0; + const originalFn = Auth.findUsersWithAuthData; + spyOn(Auth, 'findUsersWithAuthData').and.callFake((...params) => { + // First call is triggered during authData validation + if (i === 0) { + i++; + return originalFn(...params); + } + // Second call is triggered after beforeSave. A developer can modify authData during beforeSave. + // To perform a determinist login, the uniqueness of `auth.id` needs to be ensured. + // A developer with a direct access to the database could break something and duplicate authData.id. + // In this case, if 2 matching users are detected for a single authData.id, then the login/register will be canceled. + // Promise.resolve([true, true]) simulates this case with 2 matching users. + return Promise.resolve([true, true]); + }); + const user2 = new Parse.User(); + await expectAsync( + user2.save({ authData: { baseAdapter: { id: 'another' } } }) + ).toBeRejectedWithError('this auth is already used'); + }); + + it('should ensure no duplicate auth data id during authData validation in case of more than one result', async () => { + await reconfigureServer({ + auth: { baseAdapter }, + cloud: () => { + Parse.Cloud.beforeSave('_User', async request => { + request.object.set('authData', { baseAdapter: { id: 'test' } }); + }); + }, + }); + + spyOn(Auth, 'findUsersWithAuthData').and.resolveTo([true, true]); + + const user = new Parse.User(); + await expectAsync( + user.save({ authData: { baseAdapter: { id: 'another' } } }) + ).toBeRejectedWithError('this auth is already used'); + }); + + it('should pass authData, options, request to validateAuthData', async () => { + spyOn(baseAdapter, 'validateAuthData').and.resolveTo({}); + await reconfigureServer({ auth: { baseAdapter } }); + const user = new Parse.User(); + const payload = { someData: true }; + + await user.save({ + username: 'test', + password: 'password', + authData: { baseAdapter: payload }, + }); + + expect(user.getSessionToken()).toBeDefined(); + const firstCall = baseAdapter.validateAuthData.calls.argsFor(0); + expect(firstCall[0]).toEqual(payload); + expect(firstCall[1]).toEqual(baseAdapter); + expect(firstCall[2].object).toBeDefined(); + expect(firstCall[2].original).toBeUndefined(); + expect(firstCall[2].user).toBeUndefined(); + expect(firstCall[2].isChallenge).toBeUndefined(); + expect(firstCall.length).toEqual(3); + + await request({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/login', + body: JSON.stringify({ + username: 'test', + password: 'password', + authData: { baseAdapter: payload }, + }), + }); + const secondCall = baseAdapter.validateAuthData.calls.argsFor(1); + expect(secondCall[0]).toEqual(payload); + expect(secondCall[1]).toEqual(baseAdapter); + expect(secondCall[2].original).toBeDefined(); + expect(secondCall[2].original instanceof Parse.User).toBeTruthy(); + expect(secondCall[2].original.id).toEqual(user.id); + expect(secondCall[2].object).toBeDefined(); + expect(secondCall[2].object instanceof Parse.User).toBeTruthy(); + expect(secondCall[2].object.id).toEqual(user.id); + expect(secondCall[2].isChallenge).toBeUndefined(); + expect(secondCall[2].user).toBeUndefined(); + expect(secondCall.length).toEqual(3); + }); + + it('should trigger correctly validateSetUp', async () => { + spyOn(modernAdapter, 'validateSetUp').and.resolveTo({}); + spyOn(modernAdapter, 'validateUpdate').and.resolveTo({}); + spyOn(modernAdapter, 'validateLogin').and.resolveTo({}); + spyOn(modernAdapter2, 'validateSetUp').and.resolveTo({}); + spyOn(modernAdapter2, 'validateUpdate').and.resolveTo({}); + spyOn(modernAdapter2, 'validateLogin').and.resolveTo({}); + + await reconfigureServer({ auth: { modernAdapter, modernAdapter2 } }); + const user = new Parse.User(); + + await user.save({ authData: { modernAdapter: { id: 'modernAdapter' } } }); + + expect(modernAdapter.validateUpdate).toHaveBeenCalledTimes(0); + expect(modernAdapter.validateLogin).toHaveBeenCalledTimes(0); + expect(modernAdapter.validateSetUp).toHaveBeenCalledTimes(1); + const call = modernAdapter.validateSetUp.calls.argsFor(0); + expect(call[0]).toEqual({ id: 'modernAdapter' }); + expect(call[1]).toEqual(modernAdapter); + expect(call[2].isChallenge).toBeUndefined(); + expect(call[2].master).toBeDefined(); + expect(call[2].object instanceof Parse.User).toBeTruthy(); + expect(call[2].user).toBeUndefined(); + expect(call[2].original).toBeUndefined(); + expect(call[2].triggerName).toBe('validateSetUp'); + expect(call.length).toEqual(3); + expect(user.getSessionToken()).toBeDefined(); + + await user.save( + { authData: { modernAdapter2: { id: 'modernAdapter2' } } }, + { sessionToken: user.getSessionToken() } + ); + + expect(modernAdapter2.validateUpdate).toHaveBeenCalledTimes(0); + expect(modernAdapter2.validateLogin).toHaveBeenCalledTimes(0); + expect(modernAdapter2.validateSetUp).toHaveBeenCalledTimes(1); + const call2 = modernAdapter2.validateSetUp.calls.argsFor(0); + expect(call2[0]).toEqual({ id: 'modernAdapter2' }); + expect(call2[1]).toEqual(modernAdapter2); + expect(call2[2].isChallenge).toBeUndefined(); + expect(call2[2].master).toBeDefined(); + expect(call2[2].object instanceof Parse.User).toBeTruthy(); + expect(call2[2].original instanceof Parse.User).toBeTruthy(); + expect(call2[2].user instanceof Parse.User).toBeTruthy(); + expect(call2[2].original.id).toEqual(call2[2].object.id); + expect(call2[2].user.id).toEqual(call2[2].object.id); + expect(call2[2].object.id).toEqual(user.id); + expect(call2[2].triggerName).toBe('validateSetUp'); + expect(call2.length).toEqual(3); + + const user2 = new Parse.User(); + user2.id = user.id; + await user2.fetch({ useMasterKey: true }); + expect(user2.get('authData')).toEqual({ + modernAdapter: { id: 'modernAdapter' }, + modernAdapter2: { id: 'modernAdapter2' }, + }); + }); + + it('should trigger correctly validateLogin', async () => { + spyOn(modernAdapter, 'validateSetUp').and.resolveTo({}); + spyOn(modernAdapter, 'validateUpdate').and.resolveTo({}); + spyOn(modernAdapter, 'validateLogin').and.resolveTo({}); + + await reconfigureServer({ auth: { modernAdapter }, allowExpiredAuthDataToken: false }); + const user = new Parse.User(); + + await user.save({ authData: { modernAdapter: { id: 'modernAdapter' } } }); + + expect(modernAdapter.validateSetUp).toHaveBeenCalledTimes(1); + const user2 = new Parse.User(); + await user2.save({ authData: { modernAdapter: { id: 'modernAdapter' } } }); + + expect(modernAdapter.validateUpdate).toHaveBeenCalledTimes(0); + expect(modernAdapter.validateSetUp).toHaveBeenCalledTimes(1); + expect(modernAdapter.validateLogin).toHaveBeenCalledTimes(1); + const call = modernAdapter.validateLogin.calls.argsFor(0); + expect(call[0]).toEqual({ id: 'modernAdapter' }); + expect(call[1]).toEqual(modernAdapter); + expect(call[2].object instanceof Parse.User).toBeTruthy(); + expect(call[2].original instanceof Parse.User).toBeTruthy(); + expect(call[2].isChallenge).toBeUndefined(); + expect(call[2].master).toBeDefined(); + expect(call[2].user).toBeUndefined(); + expect(call[2].original.id).toEqual(user2.id); + expect(call[2].object.id).toEqual(user2.id); + expect(call[2].object.id).toEqual(user.id); + expect(call.length).toEqual(3); + expect(user2.getSessionToken()).toBeDefined(); + }); + + it('should trigger correctly validateUpdate', async () => { + spyOn(modernAdapter, 'validateSetUp').and.resolveTo({}); + spyOn(modernAdapter, 'validateUpdate').and.resolveTo({}); + spyOn(modernAdapter, 'validateLogin').and.resolveTo({}); + + await reconfigureServer({ auth: { modernAdapter } }); + const user = new Parse.User(); + + await user.save({ authData: { modernAdapter: { id: 'modernAdapter' } } }); + expect(modernAdapter.validateSetUp).toHaveBeenCalledTimes(1); + + // Save same data + await user.save( + { authData: { modernAdapter: { id: 'modernAdapter' } } }, + { sessionToken: user.getSessionToken() } + ); + + // Save same data with master key + await user.save( + { authData: { modernAdapter: { id: 'modernAdapter' } } }, + { useMasterKey: true } + ); + + expect(modernAdapter.validateUpdate).toHaveBeenCalledTimes(0); + expect(modernAdapter.validateSetUp).toHaveBeenCalledTimes(1); + expect(modernAdapter.validateLogin).toHaveBeenCalledTimes(0); + + // Change authData + await user.save( + { authData: { modernAdapter: { id: 'modernAdapter2' } } }, + { sessionToken: user.getSessionToken() } + ); + + expect(modernAdapter.validateUpdate).toHaveBeenCalledTimes(1); + expect(modernAdapter.validateSetUp).toHaveBeenCalledTimes(1); + expect(modernAdapter.validateLogin).toHaveBeenCalledTimes(0); + const call = modernAdapter.validateUpdate.calls.argsFor(0); + expect(call[0]).toEqual({ id: 'modernAdapter2' }); + expect(call[1]).toEqual(modernAdapter); + expect(call[2].isChallenge).toBeUndefined(); + expect(call[2].master).toBeDefined(); + expect(call[2].object instanceof Parse.User).toBeTruthy(); + expect(call[2].user instanceof Parse.User).toBeTruthy(); + expect(call[2].original instanceof Parse.User).toBeTruthy(); + expect(call[2].object.id).toEqual(user.id); + expect(call[2].original.id).toEqual(user.id); + expect(call[2].user.id).toEqual(user.id); + expect(call.length).toEqual(3); + expect(user.getSessionToken()).toBeDefined(); + }); + + it('should strip out authData if required', async () => { + const spy = spyOn(modernAdapter3, 'validateOptions').and.callThrough(); + const afterSpy = spyOn(modernAdapter3, 'afterFind').and.callThrough(); + await reconfigureServer({ auth: { modernAdapter3 } }); + const user = new Parse.User(); + await user.save({ authData: { modernAdapter3: { id: 'modernAdapter3Data' } } }); + await user.fetch({ sessionToken: user.getSessionToken() }); + const authData = user.get('authData').modernAdapter3; + expect(authData).toEqual({ foo: 'bar' }); + for (const call of afterSpy.calls.all()) { + const args = call.args[0]; + if (args.user) { + user._objCount = args.user._objCount; + break; + } + } + expect(afterSpy).toHaveBeenCalledWith( + { ip: '127.0.0.1', user, master: false }, + { id: 'modernAdapter3Data' }, + undefined + ); + expect(spy).toHaveBeenCalled(); + }); + + it('should throw if no triggers found', async () => { + await reconfigureServer({ auth: { wrongAdapter } }); + const user = new Parse.User(); + await expectAsync( + user.save({ authData: { wrongAdapter: { id: 'wrongAdapter' } } }) + ).toBeRejectedWithError( + 'Adapter is not configured. Implement either validateAuthData or all of the following: validateSetUp, validateLogin and validateUpdate' + ); + }); + + it('should throw if policy does not match one of default/solo/additional', async () => { + const adapterWithBadPolicy = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + policy: 'bad', + }; + await reconfigureServer({ auth: { adapterWithBadPolicy } }); + const user = new Parse.User(); + await expectAsync( + user.save({ authData: { adapterWithBadPolicy: { id: 'adapterWithBadPolicy' } } }) + ).toBeRejectedWithError( + 'AuthAdapter policy is not configured correctly. The value must be either "solo", "additional", "default" or undefined (will be handled as "default")' + ); + }); + + it('should throw if no triggers found', async () => { + await reconfigureServer({ auth: { wrongAdapter } }); + const user = new Parse.User(); + await expectAsync( + user.save({ authData: { wrongAdapter: { id: 'wrongAdapter' } } }) + ).toBeRejectedWithError( + 'Adapter is not configured. Implement either validateAuthData or all of the following: validateSetUp, validateLogin and validateUpdate' + ); + }); + + it('should not update authData if provider return doNotSave', async () => { + spyOn(doNotSaveAdapter, 'validateAuthData').and.resolveTo({ doNotSave: true }); + await reconfigureServer({ + auth: { doNotSaveAdapter, baseAdapter }, + }); + + const user = new Parse.User(); + + await user.save({ + authData: { baseAdapter: { id: 'baseAdapter' }, doNotSaveAdapter: { token: true } }, + }); + + await user.fetch({ useMasterKey: true }); + + expect(user.get('authData')).toEqual({ baseAdapter: { id: 'baseAdapter' } }); + }); + + it('should loginWith user with auth Adapter with do not save option, mutated authData and no additional auth adapter', async () => { + const spy = spyOn(doNotSaveAdapter, 'validateAuthData').and.resolveTo({ doNotSave: false }); + await reconfigureServer({ + auth: { doNotSaveAdapter, baseAdapter }, + }); + + const user = new Parse.User(); + + await user.save({ + authData: { doNotSaveAdapter: { id: 'doNotSaveAdapter' } }, + }); + + await user.fetch({ useMasterKey: true }); + + expect(user.get('authData')).toEqual({ doNotSaveAdapter: { id: 'doNotSaveAdapter' } }); + + spy.and.resolveTo({ doNotSave: true }); + + const user2 = await Parse.User.logInWith('doNotSaveAdapter', { + authData: { id: 'doNotSaveAdapter', example: 'example' }, + }); + expect(user2.getSessionToken()).toBeDefined(); + expect(user2.id).toEqual(user.id); + }); + + it('should perform authData validation only when its required', async () => { + spyOn(baseAdapter2, 'validateAuthData').and.resolveTo({}); + spyOn(baseAdapter2, 'validateAppId').and.resolveTo({}); + spyOn(baseAdapter, 'validateAuthData').and.resolveTo({}); + await reconfigureServer({ + auth: { baseAdapter2, baseAdapter }, + allowExpiredAuthDataToken: false, + }); + + const user = new Parse.User(); + + await user.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { token: true }, + }, + }); + + expect(baseAdapter2.validateAuthData).toHaveBeenCalledTimes(1); + expect(baseAdapter2.validateAppId).toHaveBeenCalledTimes(1); + + const user2 = new Parse.User(); + await user2.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + }, + }); + + expect(baseAdapter2.validateAuthData).toHaveBeenCalledTimes(1); + + const user3 = new Parse.User(); + await user3.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { token: true }, + }, + }); + + expect(baseAdapter2.validateAuthData).toHaveBeenCalledTimes(2); + }); + + it('should require additional provider if configured', async () => { + await reconfigureServer({ + auth: { baseAdapter, additionalAdapter }, + }); + + const user = new Parse.User(); + + await user.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + additionalAdapter: { token: true }, + }, + }); + + const user2 = new Parse.User(); + await expectAsync( + user2.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + }, + }) + ).toBeRejectedWithError('Missing additional authData additionalAdapter'); + expect(user2.getSessionToken()).toBeUndefined(); + + await user2.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + additionalAdapter: { token: true }, + }, + }); + + expect(user2.getSessionToken()).toBeDefined(); + }); + + it('should skip additional provider if used provider is solo', async () => { + await reconfigureServer({ + auth: { soloAdapter, additionalAdapter }, + }); + + const user = new Parse.User(); + + await user.save({ + authData: { + soloAdapter: { id: 'soloAdapter' }, + additionalAdapter: { token: true }, + }, + }); + + const user2 = new Parse.User(); + await user2.save({ + authData: { + soloAdapter: { id: 'soloAdapter' }, + }, + }); + expect(user2.getSessionToken()).toBeDefined(); + }); + + it('should return authData response and save some info on non username login', async () => { + spyOn(baseAdapter, 'validateAuthData').and.resolveTo({ + response: { someData: true }, + }); + spyOn(baseAdapter2, 'validateAuthData').and.resolveTo({ + response: { someData2: true }, + save: { otherData: true }, + }); + await reconfigureServer({ + auth: { baseAdapter, baseAdapter2 }, + }); + + const user = new Parse.User(); + + await user.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }); + + expect(user.get('authDataResponse')).toEqual({ + baseAdapter: { someData: true }, + baseAdapter2: { someData2: true }, + }); + + const user2 = new Parse.User(); + user2.id = user.id; + await user2.save( + { + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }, + { sessionToken: user.getSessionToken() } + ); + + expect(user2.get('authDataResponse')).toEqual({ baseAdapter2: { someData2: true } }); + + const user3 = new Parse.User(); + await user3.save({ + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }); + + // On logIn all authData are revalidated + expect(user3.get('authDataResponse')).toEqual({ + baseAdapter: { someData: true }, + baseAdapter2: { someData2: true }, + }); + + const userViaMasterKey = new Parse.User(); + userViaMasterKey.id = user2.id; + await userViaMasterKey.fetch({ useMasterKey: true }); + expect(userViaMasterKey.get('authData')).toEqual({ + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { otherData: true }, + }); + }); + + it('should return authData response and save some info on username login', async () => { + spyOn(baseAdapter, 'validateAuthData').and.resolveTo({ + response: { someData: true }, + }); + spyOn(baseAdapter2, 'validateAuthData').and.resolveTo({ + response: { someData2: true }, + save: { otherData: true }, + }); + await reconfigureServer({ + auth: { baseAdapter, baseAdapter2 }, + }); + + const user = new Parse.User(); + + await user.save({ + username: 'username', + password: 'password', + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }); + + expect(user.get('authDataResponse')).toEqual({ + baseAdapter: { someData: true }, + baseAdapter2: { someData2: true }, + }); + + const res = await request({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/login', + body: JSON.stringify({ + username: 'username', + password: 'password', + authData: { + baseAdapter2: { test: true }, + baseAdapter: { id: 'baseAdapter' }, + }, + }), + }); + const result = res.data; + expect(result.authDataResponse).toEqual({ + baseAdapter2: { someData2: true }, + baseAdapter: { someData: true }, + }); + + await user.fetch({ useMasterKey: true }); + expect(user.get('authData')).toEqual({ + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { otherData: true }, + }); + }); + + describe('should allow update of authData', () => { + beforeEach(async () => { + spyOn(baseAdapter, 'validateAuthData').and.resolveTo({ + response: { someData: true }, + }); + spyOn(baseAdapter2, 'validateAuthData').and.resolveTo({ + response: { someData2: true }, + save: { otherData: true }, + }); + await reconfigureServer({ + auth: { baseAdapter, baseAdapter2 }, + }); + }); + + it('should not re validate the baseAdapter when user is already logged in and authData not changed', async () => { + const user = new Parse.User(); + + await user.save({ + username: 'username', + password: 'password', + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }); + expect(baseAdapter.validateAuthData).toHaveBeenCalledTimes(1); + + expect(user.id).toBeDefined(); + expect(user.getSessionToken()).toBeDefined(); + await user.save( + { + authData: { + baseAdapter2: { test: true }, + baseAdapter: { id: 'baseAdapter' }, + }, + }, + { sessionToken: user.getSessionToken() } + ); + + expect(baseAdapter.validateAuthData).toHaveBeenCalledTimes(1); + }); + + it('should not re-validate the baseAdapter when master key is used and authData has not changed', async () => { + const user = new Parse.User(); + await user.save({ + username: 'username', + password: 'password', + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }); + await user.save( + { + authData: { + baseAdapter2: { test: true }, + baseAdapter: { id: 'baseAdapter' }, + }, + }, + { useMasterKey: true } + ); + + expect(baseAdapter.validateAuthData).toHaveBeenCalledTimes(1); + }); + + it('should allow user to change authData', async () => { + const user = new Parse.User(); + await user.save({ + username: 'username', + password: 'password', + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }); + await user.save( + { + authData: { + baseAdapter2: { test: true }, + baseAdapter: { id: 'baseAdapter2' }, + }, + }, + { sessionToken: user.getSessionToken() } + ); + + expect(baseAdapter.validateAuthData).toHaveBeenCalledTimes(2); + }); + + it('should allow master key to change authData', async () => { + const user = new Parse.User(); + await user.save({ + username: 'username', + password: 'password', + authData: { + baseAdapter: { id: 'baseAdapter' }, + baseAdapter2: { test: true }, + }, + }); + await user.save( + { + authData: { + baseAdapter2: { test: true }, + baseAdapter: { id: 'baseAdapter3' }, + }, + }, + { useMasterKey: true } + ); + + expect(baseAdapter.validateAuthData).toHaveBeenCalledTimes(2); + + await user.fetch({ useMasterKey: true }); + expect(user.get('authData')).toEqual({ + baseAdapter: { id: 'baseAdapter3' }, + baseAdapter2: { otherData: true }, + }); + }); + }); + + it('should pass user to auth adapter on update by matching session', async () => { + spyOn(baseAdapter2, 'validateAuthData').and.resolveTo({}); + await reconfigureServer({ auth: { baseAdapter2 } }); + + const user = new Parse.User(); + + const payload = { someData: true }; + + await user.save({ + username: 'test', + password: 'password', + }); + + expect(user.getSessionToken()).toBeDefined(); + + await user.save( + { authData: { baseAdapter2: payload } }, + { sessionToken: user.getSessionToken() } + ); + + const firstCall = baseAdapter2.validateAuthData.calls.argsFor(0); + expect(firstCall[0]).toEqual(payload); + expect(firstCall[1]).toEqual(baseAdapter2); + expect(firstCall[2].isChallenge).toBeUndefined(); + expect(firstCall[2].master).toBeDefined(); + expect(firstCall[2].object instanceof Parse.User).toBeTruthy(); + expect(firstCall[2].user instanceof Parse.User).toBeTruthy(); + expect(firstCall[2].original instanceof Parse.User).toBeTruthy(); + expect(firstCall[2].object.id).toEqual(user.id); + expect(firstCall[2].original.id).toEqual(user.id); + expect(firstCall[2].user.id).toEqual(user.id); + expect(firstCall.length).toEqual(3); + + await user.save({ authData: { baseAdapter2: payload } }, { useMasterKey: true }); + + const secondCall = baseAdapter2.validateAuthData.calls.argsFor(1); + expect(secondCall[0]).toEqual(payload); + expect(secondCall[1]).toEqual(baseAdapter2); + expect(secondCall[2].isChallenge).toBeUndefined(); + expect(secondCall[2].master).toEqual(true); + expect(secondCall[2].user).toBeUndefined(); + expect(secondCall[2].object instanceof Parse.User).toBeTruthy(); + expect(secondCall[2].original instanceof Parse.User).toBeTruthy(); + expect(secondCall[2].object.id).toEqual(user.id); + expect(secondCall[2].original.id).toEqual(user.id); + expect(secondCall.length).toEqual(3); + }); + + it('should return custom errors', async () => { + const throwInChallengeAdapter = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + challenge: () => Promise.reject('Invalid challenge data: yolo'), + options: { + anOption: true, + }, + }; + const throwInSetup = { + validateAppId: () => Promise.resolve(), + validateSetUp: () => Promise.reject('You cannot signup with that setup data.'), + validateUpdate: () => Promise.resolve(), + validateLogin: () => Promise.resolve(), + }; + + const throwInUpdate = { + validateAppId: () => Promise.resolve(), + validateSetUp: () => Promise.resolve(), + validateUpdate: () => Promise.reject('You cannot update with that update data.'), + validateLogin: () => Promise.resolve(), + }; + + const throwInLogin = { + validateAppId: () => Promise.resolve(), + validateSetUp: () => Promise.resolve(), + validateUpdate: () => Promise.resolve(), + validateLogin: () => Promise.reject('You cannot login with that login data.'), + }; + await reconfigureServer({ + auth: { challengeAdapter: throwInChallengeAdapter }, + }); + let logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callFake(() => {}); + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + challengeAdapter: { someData: true }, + }, + }), + }) + ).toBeRejectedWithError('Invalid challenge data: yolo'); + expect(logger.error).toHaveBeenCalledWith( + `Failed running auth step challenge for challengeAdapter for user undefined with Error: {"message":"Invalid challenge data: yolo","code":${Parse.Error.SCRIPT_FAILED}}`, + { + authenticationStep: 'challenge', + error: new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Invalid challenge data: yolo'), + user: undefined, + provider: 'challengeAdapter', + } + ); + + await reconfigureServer({ auth: { modernAdapter: throwInSetup } }); + logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callFake(() => {}); + let user = new Parse.User(); + await expectAsync( + user.save({ authData: { modernAdapter: { id: 'modernAdapter' } } }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.SCRIPT_FAILED, 'You cannot signup with that setup data.') + ); + expect(logger.error).toHaveBeenCalledWith( + `Failed running auth step validateSetUp for modernAdapter for user undefined with Error: {"message":"You cannot signup with that setup data.","code":${Parse.Error.SCRIPT_FAILED}}`, + { + authenticationStep: 'validateSetUp', + error: new Parse.Error( + Parse.Error.SCRIPT_FAILED, + 'You cannot signup with that setup data.' + ), + user: undefined, + provider: 'modernAdapter', + } + ); + + await reconfigureServer({ auth: { modernAdapter: throwInUpdate } }); + logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callFake(() => {}); + user = new Parse.User(); + await user.save({ authData: { modernAdapter: { id: 'updateAdapter' } } }); + await expectAsync( + user.save( + { authData: { modernAdapter: { id: 'updateAdapter2' } } }, + { sessionToken: user.getSessionToken() } + ) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.SCRIPT_FAILED, 'You cannot update with that update data.') + ); + + expect(logger.error).toHaveBeenCalledWith( + `Failed running auth step validateUpdate for modernAdapter for user ${user.id} with Error: {"message":"You cannot update with that update data.","code":${Parse.Error.SCRIPT_FAILED}}`, + { + authenticationStep: 'validateUpdate', + error: new Parse.Error( + Parse.Error.SCRIPT_FAILED, + 'You cannot update with that update data.' + ), + user: user.id, + provider: 'modernAdapter', + } + ); + + await reconfigureServer({ + auth: { modernAdapter: throwInLogin }, + allowExpiredAuthDataToken: false, + }); + logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callFake(() => {}); + user = new Parse.User(); + await user.save({ authData: { modernAdapter: { id: 'modernAdapter' } } }); + const user2 = new Parse.User(); + await expectAsync( + user2.save({ authData: { modernAdapter: { id: 'modernAdapter' } } }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.SCRIPT_FAILED, 'You cannot login with that login data.') + ); + expect(logger.error).toHaveBeenCalledWith( + `Failed running auth step validateLogin for modernAdapter for user ${user.id} with Error: {"message":"You cannot login with that login data.","code":${Parse.Error.SCRIPT_FAILED}}`, + { + authenticationStep: 'validateLogin', + error: new Parse.Error(Parse.Error.SCRIPT_FAILED, 'You cannot login with that login data.'), + user: user.id, + provider: 'modernAdapter', + } + ); + }); + + it('should return challenge with no logged user', async () => { + spyOn(challengeAdapter, 'challenge').and.resolveTo({ token: 'test' }); + + await reconfigureServer({ + auth: { challengeAdapter }, + }); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: {}, + }) + ).toBeRejectedWithError('Nothing to challenge.'); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: { challengeData: true }, + }) + ).toBeRejectedWithError('challengeData should be an object.'); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: { challengeData: { data: true }, authData: true }, + }) + ).toBeRejectedWithError('authData should be an object.'); + + const res = await request({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + challengeAdapter: { someData: true }, + }, + }), + }); + + expect(res.data).toEqual({ + challengeData: { + challengeAdapter: { + token: 'test', + }, + }, + }); + const challengeCall = challengeAdapter.challenge.calls.argsFor(0); + expect(challengeAdapter.challenge).toHaveBeenCalledTimes(1); + expect(challengeCall[0]).toEqual({ someData: true }); + expect(challengeCall[1]).toBeUndefined(); + expect(challengeCall[2]).toEqual(challengeAdapter); + expect(challengeCall[3].master).toBeDefined(); + expect(challengeCall[3].headers).toBeDefined(); + expect(challengeCall[3].object).toBeUndefined(); + expect(challengeCall[3].original).toBeUndefined(); + expect(challengeCall[3].user).toBeUndefined(); + expect(challengeCall[3].isChallenge).toBeTruthy(); + expect(challengeCall.length).toEqual(4); + }); + + it('should return empty challenge data response if challenged provider does not exists', async () => { + spyOn(challengeAdapter, 'challenge').and.resolveTo({ token: 'test' }); + + await reconfigureServer({ + auth: { challengeAdapter }, + }); + + const res = await request({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + nonExistingProvider: { someData: true }, + }, + }), + }); + + expect(res.data).toEqual({ challengeData: {} }); + }); + it('should return challenge with username created user', async () => { + spyOn(challengeAdapter, 'challenge').and.resolveTo({ token: 'test' }); + + await reconfigureServer({ + auth: { challengeAdapter }, + }); + + const user = new Parse.User(); + await user.save({ username: 'username', password: 'password' }); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + username: 'username', + challengeData: { + challengeAdapter: { someData: true }, + }, + }), + }) + ).toBeRejectedWithError('You provided username or email, you need to also provide password.'); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + username: 'username', + password: 'password', + authData: { data: true }, + challengeData: { + challengeAdapter: { someData: true }, + }, + }), + }) + ).toBeRejectedWithError( + 'You cannot provide username/email and authData, only use one identification method.' + ); + + const res = await request({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + username: 'username', + password: 'password', + challengeData: { + challengeAdapter: { someData: true }, + }, + }), + }); + + expect(res.data).toEqual({ + challengeData: { + challengeAdapter: { + token: 'test', + }, + }, + }); + + const challengeCall = challengeAdapter.challenge.calls.argsFor(0); + expect(challengeAdapter.challenge).toHaveBeenCalledTimes(1); + expect(challengeCall[0]).toEqual({ someData: true }); + expect(challengeCall[1]).toEqual(undefined); + expect(challengeCall[2]).toEqual(challengeAdapter); + expect(challengeCall[3].master).toBeDefined(); + expect(challengeCall[3].isChallenge).toBeTruthy(); + expect(challengeCall[3].user).toBeUndefined(); + expect(challengeCall[3].object instanceof Parse.User).toBeTruthy(); + expect(challengeCall[3].original instanceof Parse.User).toBeTruthy(); + expect(challengeCall[3].object.id).toEqual(user.id); + expect(challengeCall[3].original.id).toEqual(user.id); + expect(challengeCall.length).toEqual(4); + }); + + it('should return challenge with authData created user', async () => { + spyOn(challengeAdapter, 'challenge').and.resolveTo({ token: 'test' }); + spyOn(challengeAdapter, 'validateAuthData').and.callThrough(); + + await reconfigureServer({ + auth: { challengeAdapter, soloAdapter }, + }); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + challengeAdapter: { someData: true }, + }, + authData: { + challengeAdapter: { id: 'challengeAdapter' }, + }, + }), + }) + ).toBeRejectedWithError('User not found.'); + + const user = new Parse.User(); + await user.save({ authData: { challengeAdapter: { id: 'challengeAdapter' } } }); + + const user2 = new Parse.User(); + await user2.save({ authData: { soloAdapter: { id: 'soloAdapter' } } }); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + challengeAdapter: { someData: true }, + }, + authData: { + challengeAdapter: { id: 'challengeAdapter' }, + soloAdapter: { id: 'soloAdapter' }, + }, + }), + }) + ).toBeRejectedWithError('You cannot provide more than one authData provider with an id.'); + + const res = await request({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + challengeAdapter: { someData: true }, + }, + authData: { + challengeAdapter: { id: 'challengeAdapter' }, + }, + }), + }); + + expect(res.data).toEqual({ + challengeData: { + challengeAdapter: { + token: 'test', + }, + }, + }); + + const validateCall = challengeAdapter.validateAuthData.calls.argsFor(1); + expect(validateCall[2].isChallenge).toBeTruthy(); + + const challengeCall = challengeAdapter.challenge.calls.argsFor(0); + expect(challengeAdapter.challenge).toHaveBeenCalledTimes(1); + expect(challengeCall[0]).toEqual({ someData: true }); + expect(challengeCall[1]).toEqual({ id: 'challengeAdapter' }); + expect(challengeCall[2]).toEqual(challengeAdapter); + expect(challengeCall[3].master).toBeDefined(); + expect(challengeCall[3].isChallenge).toBeTruthy(); + expect(challengeCall[3].object instanceof Parse.User).toBeTruthy(); + expect(challengeCall[3].original instanceof Parse.User).toBeTruthy(); + expect(challengeCall[3].object.id).toEqual(user.id); + expect(challengeCall[3].original.id).toEqual(user.id); + expect(challengeCall.length).toEqual(4); + }); + + it('should validate provided authData and prevent guess id attack', async () => { + spyOn(challengeAdapter, 'challenge').and.resolveTo({ token: 'test' }); + + await reconfigureServer({ + auth: { challengeAdapter, soloAdapter }, + }); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + challengeAdapter: { someData: true }, + }, + authData: { + challengeAdapter: { id: 'challengeAdapter' }, + }, + }), + }) + ).toBeRejectedWithError('User not found.'); + + const user = new Parse.User(); + await user.save({ authData: { challengeAdapter: { id: 'challengeAdapter' } } }); + + spyOn(challengeAdapter, 'validateAuthData').and.rejectWith({}); + + await expectAsync( + requestWithExpectedError({ + headers: headers, + method: 'POST', + url: 'http://localhost:8378/1/challenge', + body: JSON.stringify({ + challengeData: { + challengeAdapter: { someData: true }, + }, + authData: { + challengeAdapter: { id: 'challengeAdapter' }, + }, + }), + }) + ).toBeRejectedWithError('User not found.'); + + const validateCall = challengeAdapter.validateAuthData.calls.argsFor(0); + expect(challengeAdapter.validateAuthData).toHaveBeenCalledTimes(1); + expect(validateCall[0]).toEqual({ id: 'challengeAdapter' }); + expect(validateCall[1]).toEqual(challengeAdapter); + expect(validateCall[2].isChallenge).toBeTruthy(); + expect(validateCall[2].master).toBeDefined(); + expect(validateCall[2].object instanceof Parse.User).toBeTruthy(); + expect(validateCall[2].original instanceof Parse.User).toBeTruthy(); + expect(validateCall[2].object.id).toEqual(user.id); + expect(validateCall[2].original.id).toEqual(user.id); + expect(validateCall.length).toEqual(3); + }); + + it('should work with multiple adapters', async () => { + const adapterA = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + }; + const adapterB = { + validateAppId: () => Promise.resolve(), + validateAuthData: () => Promise.resolve(), + }; + await reconfigureServer({ auth: { adapterA, adapterB } }); + const user = new Parse.User(); + await user.signUp({ + username: 'test', + password: 'password', + }); + await user.save({ authData: { adapterA: { id: 'testA' } } }); + expect(user.get('authData')).toEqual({ adapterA: { id: 'testA' } }); + await user.save({ authData: { adapterA: null, adapterB: { id: 'test' } } }); + await user.fetch({ useMasterKey: true }); + expect(user.get('authData')).toEqual({ adapterB: { id: 'test' } }); + }); +}); diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 540f02abf6..d73b854a9b 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -74,7 +74,7 @@ describe('commander additions', () => { done(); }); - it('should load properly use args over env', done => { + it('should load properly use args over env', () => { commander.loadDefinitions(testDefinitions); commander.parse(['node', './CLI.spec.js', '--arg0', 'arg0Value', '--arg4', ''], { PROGRAM_ARG_0: 'arg0ENVValue', @@ -86,7 +86,6 @@ describe('commander additions', () => { expect(commander.arg1).toEqual('arg1ENVValue'); expect(commander.arg2).toEqual(4); expect(commander.arg4).toEqual(''); - done(); }); it('should fail in action as port is invalid', done => { @@ -219,17 +218,14 @@ describe('execution', () => { } }); - it('shoud start Parse Server', done => { - childProcess = spawn(binPath, [ - '--appId', - 'test', - '--masterKey', - 'test', - '--databaseURI', - 'mongodb://localhost/test', - '--port', - '1339', - ]); + it('should start Parse Server', done => { + const env = { ...process.env }; + env.NODE_OPTIONS = '--dns-result-order=ipv4first'; + childProcess = spawn( + binPath, + ['--appId', 'test', '--masterKey', 'test', '--databaseURI', databaseURI, '--port', '1339'], + { env } + ); childProcess.stdout.on('data', data => { data = data.toString(); if (data.includes('parse-server running on')) { @@ -241,18 +237,24 @@ describe('execution', () => { }); }); - it('shoud start Parse Server with GraphQL', done => { - childProcess = spawn(binPath, [ - '--appId', - 'test', - '--masterKey', - 'test', - '--databaseURI', - 'mongodb://localhost/test', - '--port', - '1340', - '--mountGraphQL', - ]); + it('should start Parse Server with GraphQL', async done => { + const env = { ...process.env }; + env.NODE_OPTIONS = '--dns-result-order=ipv4first'; + childProcess = spawn( + binPath, + [ + '--appId', + 'test', + '--masterKey', + 'test', + '--databaseURI', + databaseURI, + '--port', + '1340', + '--mountGraphQL', + ], + { env } + ); let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); @@ -267,19 +269,25 @@ describe('execution', () => { }); }); - it('shoud start Parse Server with GraphQL and Playground', done => { - childProcess = spawn(binPath, [ - '--appId', - 'test', - '--masterKey', - 'test', - '--databaseURI', - 'mongodb://localhost/test', - '--port', - '1341', - '--mountGraphQL', - '--mountPlayground', - ]); + it('should start Parse Server with GraphQL and Playground', async done => { + const env = { ...process.env }; + env.NODE_OPTIONS = '--dns-result-order=ipv4first'; + childProcess = spawn( + binPath, + [ + '--appId', + 'test', + '--masterKey', + 'test', + '--databaseURI', + databaseURI, + '--port', + '1341', + '--mountGraphQL', + '--mountPlayground', + ], + { env } + ); let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); @@ -294,4 +302,25 @@ describe('execution', () => { done.fail(data.toString()); }); }); + + it('can start Parse Server with auth via CLI', done => { + const env = { ...process.env }; + env.NODE_OPTIONS = '--dns-result-order=ipv4first'; + childProcess = spawn( + binPath, + ['--databaseURI', databaseURI, './spec/configs/CLIConfigAuth.json'], + { env } + ); + childProcess.stdout.on('data', data => { + data = data.toString(); + console.log(data); + if (data.includes('parse-server running on')) { + done(); + } + }); + childProcess.stderr.on('data', data => { + data = data.toString(); + done.fail(data.toString()); + }); + }); }); diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index c522af0b5d..239a58d39f 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1,6 +1,7 @@ 'use strict'; const Config = require('../lib/Config'); const Parse = require('parse/node'); +const ParseServer = require('../lib/index').ParseServer; const request = require('../lib/request'); const InMemoryCacheAdapter = require('../lib/Adapters/Cache/InMemoryCacheAdapter') .InMemoryCacheAdapter; @@ -39,6 +40,47 @@ describe('Cloud Code', () => { }); }); + it('can load cloud code as a module', async () => { + process.env.npm_package_type = 'module'; + await reconfigureServer({ appId: 'test1', cloud: './spec/cloud/cloudCodeModuleFile.js' }); + const result = await Parse.Cloud.run('cloudCodeInFile'); + expect(result).toEqual('It is possible to define cloud code in a file.'); + delete process.env.npm_package_type; + }); + + it('cloud code must be valid type', async () => { + await expectAsync(reconfigureServer({ cloud: true })).toBeRejectedWith( + "argument 'cloud' must either be a string or a function" + ); + }); + + it('should wait for cloud code to load', async () => { + await reconfigureServer({ appId: 'test3' }); + const initiated = new Date(); + const parseServer = await new ParseServer({ + ...defaultConfiguration, + appId: 'test3', + masterKey: 'test', + serverURL: 'http://localhost:12668/parse', + async cloud() { + await new Promise(resolve => setTimeout(resolve, 1000)); + Parse.Cloud.beforeSave('Test', () => { + throw 'Cannot save.'; + }); + }, + }).start(); + const express = require('express'); + const app = express(); + app.use('/parse', parseServer.app); + const server = app.listen(12668); + const now = new Date(); + expect(now.getTime() - initiated.getTime() > 1000).toBeTrue(); + await expectAsync(new Parse.Object('Test').save()).toBeRejectedWith( + new Parse.Error(141, 'Cannot save.') + ); + await new Promise(resolve => server.close(resolve)); + }); + it('can create functions', done => { Parse.Cloud.define('hello', () => { return 'Hello world!'; @@ -53,13 +95,22 @@ describe('Cloud Code', () => { it('can get config', () => { const config = Parse.Server; let currentConfig = Config.get('test'); - expect(Object.keys(config)).toEqual(Object.keys(currentConfig)); + const server = require('../lib/cloud-code/Parse.Server'); + expect(Object.keys(config)).toEqual(Object.keys({ ...currentConfig, ...server })); config.silent = false; Parse.Server = config; currentConfig = Config.get('test'); expect(currentConfig.silent).toBeFalse(); }); + it('can get curent version', () => { + const version = require('../package.json').version; + const currentConfig = Config.get('test'); + expect(Parse.Server.version).toBeDefined(); + expect(currentConfig.version).toBeDefined(); + expect(Parse.Server.version).toEqual(version); + }); + it('show warning on duplicate cloud functions', done => { const logger = require('../lib/logger').logger; spyOn(logger, 'warn').and.callFake(() => {}); @@ -1310,6 +1361,47 @@ describe('Cloud Code', () => { }); }); + it('should not encode Parse Objects', async () => { + const user = new Parse.User(); + user.setUsername('username'); + user.setPassword('password'); + user.set('deleted', false); + await user.signUp(); + Parse.Cloud.define( + 'deleteAccount', + async req => { + expect(req.params.object instanceof Parse.Object).not.toBeTrue(); + return 'Object deleted'; + }, + { + requireMaster: true, + } + ); + await Parse.Cloud.run('deleteAccount', { object: user.toPointer() }, { useMasterKey: true }); + }); + + it('allow cloud to encode Parse Objects', async () => { + await reconfigureServer({ encodeParseObjectInCloudFunction: true }); + const user = new Parse.User(); + user.setUsername('username'); + user.setPassword('password'); + user.set('deleted', false); + await user.signUp(); + Parse.Cloud.define( + 'deleteAccount', + async req => { + expect(req.params.object instanceof Parse.Object).toBeTrue(); + req.params.object.set('deleted', true); + await req.params.object.save(null, { useMasterKey: true }); + return 'Object deleted'; + }, + { + requireMaster: true, + } + ); + await Parse.Cloud.run('deleteAccount', { object: user.toPointer() }, { useMasterKey: true }); + }); + it('beforeSave should not affect fetched pointers', done => { Parse.Cloud.beforeSave('BeforeSaveUnchanged', () => {}); @@ -1558,6 +1650,22 @@ describe('Cloud Code', () => { expect(obj.get('foo')).toBe('bar'); }); + it('create role with name and ACL and a beforeSave', async () => { + Parse.Cloud.beforeSave(Parse.Role, ({ object }) => { + return object; + }); + + const obj = new Parse.Role('TestRole', new Parse.ACL({ '*': { read: true, write: true } })); + await obj.save(); + + expect(obj.getACL()).toEqual(new Parse.ACL({ '*': { read: true, write: true } })); + expect(obj.get('name')).toEqual('TestRole'); + await obj.fetch(); + + expect(obj.getACL()).toEqual(new Parse.ACL({ '*': { read: true, write: true } })); + expect(obj.get('name')).toEqual('TestRole'); + }); + it('can unset in afterSave', async () => { Parse.Cloud.beforeSave('TestObject', ({ object }) => { if (!object.existed()) { @@ -1686,25 +1794,6 @@ describe('Cloud Code', () => { obj.save().then(done, done.fail); }); - it('can deprecate Parse.Cloud.httpRequest', async () => { - const logger = require('../lib/logger').logger; - spyOn(logger, 'warn').and.callFake(() => {}); - Parse.Cloud.define('hello', () => { - return 'Hello world!'; - }); - await Parse.Cloud.httpRequest({ - method: 'POST', - url: 'http://localhost:8378/1/functions/hello', - headers: { - 'X-Parse-Application-Id': Parse.applicationId, - 'X-Parse-REST-API-Key': 'rest', - }, - }); - expect(logger.warn).toHaveBeenCalledWith( - 'DeprecationWarning: Parse.Cloud.httpRequest is deprecated and will be removed in a future version. Use a http request library instead.' - ); - }); - describe('cloud jobs', () => { it('should define a job', done => { expect(() => { @@ -2309,6 +2398,56 @@ describe('beforeFind hooks', () => { }); }); + it('sets correct beforeFind trigger isGet parameter for Parse.Object.fetch request', async () => { + const hook = { + method: req => { + expect(req.isGet).toEqual(true); + return Promise.resolve(); + }, + }; + spyOn(hook, 'method').and.callThrough(); + Parse.Cloud.beforeFind('MyObject', hook.method); + const obj = new Parse.Object('MyObject'); + await obj.save(); + const getObj = await obj.fetch(); + expect(getObj).toBeInstanceOf(Parse.Object); + expect(hook.method).toHaveBeenCalledTimes(1); + }); + + it('sets correct beforeFind trigger isGet parameter for Parse.Query.get request', async () => { + const hook = { + method: req => { + expect(req.isGet).toEqual(false); + return Promise.resolve(); + }, + }; + spyOn(hook, 'method').and.callThrough(); + Parse.Cloud.beforeFind('MyObject', hook.method); + const obj = new Parse.Object('MyObject'); + await obj.save(); + const query = new Parse.Query('MyObject'); + const getObj = await query.get(obj.id); + expect(getObj).toBeInstanceOf(Parse.Object); + expect(hook.method).toHaveBeenCalledTimes(1); + }); + + it('sets correct beforeFind trigger isGet parameter for Parse.Query.find request', async () => { + const hook = { + method: req => { + expect(req.isGet).toEqual(false); + return Promise.resolve(); + }, + }; + spyOn(hook, 'method').and.callThrough(); + Parse.Cloud.beforeFind('MyObject', hook.method); + const obj = new Parse.Object('MyObject'); + await obj.save(); + const query = new Parse.Query('MyObject'); + const findObjs = await query.find(); + expect(findObjs?.[0]).toBeInstanceOf(Parse.Object); + expect(hook.method).toHaveBeenCalledTimes(1); + }); + it('should have request headers', done => { Parse.Cloud.beforeFind('MyObject', req => { expect(req.headers).toBeDefined(); @@ -2342,6 +2481,60 @@ describe('beforeFind hooks', () => { }) .then(() => done()); }); + + it('should run beforeFind on pointers and array of pointers from an object', async () => { + const obj1 = new Parse.Object('TestObject'); + const obj2 = new Parse.Object('TestObject2'); + const obj3 = new Parse.Object('TestObject'); + obj2.set('aField', 'aFieldValue'); + await obj2.save(); + obj1.set('pointerField', obj2); + obj3.set('pointerFieldArray', [obj2]); + await obj1.save(); + await obj3.save(); + const spy = jasmine.createSpy('beforeFindSpy'); + Parse.Cloud.beforeFind('TestObject2', spy); + const query = new Parse.Query('TestObject'); + await query.get(obj1.id); + // Pointer not included in query so we don't expect beforeFind to be called + expect(spy).not.toHaveBeenCalled(); + const query2 = new Parse.Query('TestObject'); + query2.include('pointerField'); + const res = await query2.get(obj1.id); + expect(res.get('pointerField').get('aField')).toBe('aFieldValue'); + // Pointer included in query so we expect beforeFind to be called + expect(spy).toHaveBeenCalledTimes(1); + const query3 = new Parse.Query('TestObject'); + query3.include('pointerFieldArray'); + const res2 = await query3.get(obj3.id); + expect(res2.get('pointerFieldArray')[0].get('aField')).toBe('aFieldValue'); + expect(spy).toHaveBeenCalledTimes(2); + }); + + it('should have access to context in include query in beforeFind hook', async () => { + let beforeFindTestObjectCalled = false; + let beforeFindTestObject2Called = false; + const obj1 = new Parse.Object('TestObject'); + const obj2 = new Parse.Object('TestObject2'); + obj2.set('aField', 'aFieldValue'); + await obj2.save(); + obj1.set('pointerField', obj2); + await obj1.save(); + Parse.Cloud.beforeFind('TestObject', req => { + expect(req.context).toBeDefined(); + expect(req.context.a).toEqual('a'); + beforeFindTestObjectCalled = true; + }); + Parse.Cloud.beforeFind('TestObject2', req => { + expect(req.context).toBeDefined(); + expect(req.context.a).toEqual('a'); + beforeFindTestObject2Called = true; + }); + const query = new Parse.Query('TestObject'); + await query.include('pointerField').find({ context: { a: 'a' } }); + expect(beforeFindTestObjectCalled).toBeTrue(); + expect(beforeFindTestObject2Called).toBeTrue(); + }); }); describe('afterFind hooks', () => { @@ -2735,7 +2928,7 @@ describe('afterFind hooks', () => { const obj = new Parse.Object('MyObject'); const pipeline = [ { - group: { objectId: {} }, + $group: { _id: {} }, }, ]; obj @@ -3122,6 +3315,36 @@ describe('beforeLogin hook', () => { done(); }); + it('does not crash server when throwing in afterLogin hook', async () => { + const error = new Parse.Error(2000, 'afterLogin error'); + const trigger = { + afterLogin() { + throw error; + }, + }; + const spy = spyOn(trigger, 'afterLogin').and.callThrough(); + Parse.Cloud.afterLogin(trigger.afterLogin); + await Parse.User.signUp('user', 'pass'); + const response = await Parse.User.logIn('user', 'pass').catch(e => e); + expect(spy).toHaveBeenCalled(); + expect(response).toEqual(error); + }); + + it('does not crash server when throwing in afterLogout hook', async () => { + const error = new Parse.Error(2000, 'afterLogout error'); + const trigger = { + afterLogout() { + throw error; + }, + }; + const spy = spyOn(trigger, 'afterLogout').and.callThrough(); + Parse.Cloud.afterLogout(trigger.afterLogout); + await Parse.User.signUp('user', 'pass'); + const response = await Parse.User.logOut().catch(e => e); + expect(spy).toHaveBeenCalled(); + expect(response).toEqual(error); + }); + it('should have expected data in request', async done => { Parse.Cloud.beforeLogin(req => { expect(req.object).toBeDefined(); @@ -3129,7 +3352,7 @@ describe('beforeLogin hook', () => { expect(req.headers).toBeDefined(); expect(req.ip).toBeDefined(); expect(req.installationId).toBeDefined(); - expect(req.context).toBeUndefined(); + expect(req.context).toBeDefined(); }); await Parse.User.signUp('tupac', 'shakur'); @@ -3246,7 +3469,7 @@ describe('afterLogin hook', () => { expect(req.headers).toBeDefined(); expect(req.ip).toBeDefined(); expect(req.installationId).toBeDefined(); - expect(req.context).toBeUndefined(); + expect(req.context).toBeDefined(); }); await Parse.User.signUp('testuser', 'p@ssword'); @@ -3412,7 +3635,7 @@ describe('afterLogin hook', () => { }); describe('saveFile hooks', () => { - it('beforeSaveFile should return file that is already saved and not save anything to files adapter', async () => { + it('beforeSave(Parse.File) should return file that is already saved and not save anything to files adapter', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough(); Parse.Cloud.beforeSave(Parse.File, () => { @@ -3428,7 +3651,7 @@ describe('saveFile hooks', () => { expect(createFileSpy).not.toHaveBeenCalled(); }); - it('beforeSaveFile should throw error', async () => { + it('beforeSave(Parse.File) should throw error', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.beforeSave(Parse.File, () => { throw new Parse.Error(400, 'some-error-message'); @@ -3441,7 +3664,7 @@ describe('saveFile hooks', () => { } }); - it('beforeSaveFile should change values of uploaded file by editing fileObject directly', async () => { + it('beforeSave(Parse.File) should change values of uploaded file by editing fileObject directly', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough(); Parse.Cloud.beforeSave(Parse.File, async req => { @@ -3470,7 +3693,7 @@ describe('saveFile hooks', () => { ); }); - it('beforeSaveFile should change values by returning new fileObject', async () => { + it('beforeSave(Parse.File) should change values by returning new fileObject', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough(); Parse.Cloud.beforeSave(Parse.File, async req => { @@ -3504,7 +3727,7 @@ describe('saveFile hooks', () => { expect(file._name.indexOf(expectedFileName)).toBe(file._name.length - expectedFileName.length); }); - it('beforeSaveFile should contain metadata and tags saved from client', async () => { + it('beforeSave(Parse.File) should contain metadata and tags saved from client', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough(); Parse.Cloud.beforeSave(Parse.File, async req => { @@ -3532,7 +3755,7 @@ describe('saveFile hooks', () => { ); }); - it('beforeSaveFile should return same file data with new file name', async () => { + it('beforeSave(Parse.File) should return same file data with new file name', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); const config = Config.get('test'); config.filesController.options.preserveFileName = true; @@ -3547,7 +3770,7 @@ describe('saveFile hooks', () => { expect(result.name()).toBe('2020-04-01.txt'); }); - it('afterSaveFile should set fileSize to null if beforeSave returns an already saved file', async () => { + it('afterSave(Parse.File) should set fileSize to null if beforeSave returns an already saved file', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); const createFileSpy = spyOn(mockAdapter, 'createFile').and.callThrough(); Parse.Cloud.beforeSave(Parse.File, req => { @@ -3567,7 +3790,7 @@ describe('saveFile hooks', () => { expect(createFileSpy).not.toHaveBeenCalled(); }); - it('afterSaveFile should throw error', async () => { + it('afterSave(Parse.File) should throw error', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.afterSave(Parse.File, async () => { throw new Parse.Error(400, 'some-error-message'); @@ -3581,7 +3804,7 @@ describe('saveFile hooks', () => { } }); - it('afterSaveFile should call with fileObject', async done => { + it('afterSave(Parse.File) should call with fileObject', async done => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.beforeSave(Parse.File, async req => { req.file.setTags({ tagA: 'some-tag' }); @@ -3597,7 +3820,7 @@ describe('saveFile hooks', () => { await file.save({ useMasterKey: true }); }); - it('afterSaveFile should change fileSize when file data changes', async done => { + it('afterSave(Parse.File) should change fileSize when file data changes', async done => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.beforeSave(Parse.File, async req => { expect(req.fileSize).toBe(3); @@ -3614,7 +3837,7 @@ describe('saveFile hooks', () => { await file.save({ useMasterKey: true }); }); - it('beforeDeleteFile should call with fileObject', async () => { + it('beforeDelete(Parse.File) should call with fileObject', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.beforeDelete(Parse.File, req => { expect(req.file).toBeInstanceOf(Parse.File); @@ -3626,7 +3849,7 @@ describe('saveFile hooks', () => { await file.destroy({ useMasterKey: true }); }); - it('beforeDeleteFile should throw error', async done => { + it('beforeDelete(Parse.File) should throw error', async done => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.beforeDelete(Parse.File, () => { throw new Error('some error message'); @@ -3640,7 +3863,7 @@ describe('saveFile hooks', () => { } }); - it('afterDeleteFile should call with fileObject', async done => { + it('afterDelete(Parse.File) should call with fileObject', async done => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.beforeDelete(Parse.File, req => { expect(req.file).toBeInstanceOf(Parse.File); @@ -3657,7 +3880,7 @@ describe('saveFile hooks', () => { await file.destroy({ useMasterKey: true }); }); - it('beforeSaveFile should not change file if nothing is returned', async () => { + it('beforeSave(Parse.File) should not change file if nothing is returned', async () => { await reconfigureServer({ filesAdapter: mockAdapter }); Parse.Cloud.beforeSave(Parse.File, () => { return; @@ -3667,7 +3890,7 @@ describe('saveFile hooks', () => { expect(result).toBe(file); }); - it('throw custom error from beforeSaveFile', async done => { + it('throw custom error from beforeSave(Parse.File) ', async done => { Parse.Cloud.beforeSave(Parse.File, () => { throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'It should fail'); }); @@ -3681,7 +3904,7 @@ describe('saveFile hooks', () => { } }); - it('throw empty error from beforeSaveFile', async done => { + it('throw empty error from beforeSave(Parse.File)', async done => { Parse.Cloud.beforeSave(Parse.File, () => { throw null; }); @@ -3694,55 +3917,6 @@ describe('saveFile hooks', () => { done(); } }); - - it('legacy hooks', async () => { - await reconfigureServer({ filesAdapter: mockAdapter }); - const logger = require('../lib/logger').logger; - const logSpy = spyOn(logger, 'warn').and.callFake(() => {}); - const triggers = { - beforeSaveFile(req) { - req.file.setTags({ tagA: 'some-tag' }); - req.file.setMetadata({ foo: 'bar' }); - expect(req.triggerName).toEqual('beforeSave'); - expect(req.master).toBe(true); - }, - afterSaveFile(req) { - expect(req.master).toBe(true); - expect(req.file._tags).toEqual({ tagA: 'some-tag' }); - expect(req.file._metadata).toEqual({ foo: 'bar' }); - }, - beforeDeleteFile(req) { - expect(req.file).toBeInstanceOf(Parse.File); - expect(req.file._name).toEqual('popeye.txt'); - expect(req.file._url).toEqual('http://www.somewhere.com/popeye.txt'); - expect(req.fileSize).toBe(null); - }, - afterDeleteFile(req) { - expect(req.file).toBeInstanceOf(Parse.File); - expect(req.file._name).toEqual('popeye.txt'); - expect(req.file._url).toEqual('http://www.somewhere.com/popeye.txt'); - }, - }; - - for (const key in triggers) { - spyOn(triggers, key).and.callThrough(); - Parse.Cloud[key](triggers[key]); - } - - const file = new Parse.File('popeye.txt', [1, 2, 3], 'text/plain'); - await file.save({ useMasterKey: true }); - await new Parse.File('popeye.txt', [1, 2, 3], 'text/plain').destroy({ useMasterKey: true }); - await new Promise(resolve => setTimeout(resolve, 100)); - for (const key in triggers) { - expect(triggers[key]).toHaveBeenCalled(); - expect(logSpy).toHaveBeenCalledWith( - `DeprecationWarning: Parse.Cloud.${key} is deprecated and will be removed in a future version. Use Parse.Cloud.${key.replace( - 'File', - '' - )}(Parse.File, (request) => {})` - ); - } - }); }); describe('sendEmail', () => { diff --git a/spec/CloudCodeLogger.spec.js b/spec/CloudCodeLogger.spec.js index 162a3390b7..b4dd5a42d8 100644 --- a/spec/CloudCodeLogger.spec.js +++ b/spec/CloudCodeLogger.spec.js @@ -182,6 +182,77 @@ describe('Cloud Code Logger', () => { }); }); + it('should log cloud function execution using the custom log level', async done => { + Parse.Cloud.define('aFunction', () => { + return 'it worked!'; + }); + + Parse.Cloud.define('bFunction', () => { + throw new Error('Failed'); + }); + + await Parse.Cloud.run('aFunction', { foo: 'bar' }).then(() => { + const log = spy.calls.allArgs().find(log => log[1].startsWith('Ran cloud function '))?.[0]; + expect(log).toEqual('info'); + }); + + await reconfigureServer({ + silent: true, + logLevels: { + cloudFunctionSuccess: 'warn', + cloudFunctionError: 'info', + }, + }); + + spy = spyOn(Config.get('test').loggerController.adapter, 'log').and.callThrough(); + + try { + await Parse.Cloud.run('bFunction', { foo: 'bar' }); + throw new Error('bFunction should have failed'); + } catch { + const log = spy.calls + .allArgs() + .find(log => log[1].startsWith('Failed running cloud function bFunction for '))?.[0]; + expect(log).toEqual('info'); + done(); + } + }); + + it('should log cloud function triggers using the custom log level', async () => { + Parse.Cloud.beforeSave('TestClass', () => {}); + Parse.Cloud.afterSave('TestClass', () => {}); + + const execTest = async (logLevel, triggerBeforeSuccess, triggerAfter) => { + await reconfigureServer({ + silent: true, + logLevel, + logLevels: { + triggerAfter, + triggerBeforeSuccess, + }, + }); + + spy = spyOn(Config.get('test').loggerController.adapter, 'log').and.callThrough(); + const obj = new Parse.Object('TestClass'); + await obj.save(); + + return { + beforeSave: spy.calls + .allArgs() + .find(log => log[1].startsWith('beforeSave triggered for TestClass for user '))?.[0], + afterSave: spy.calls + .allArgs() + .find(log => log[1].startsWith('afterSave triggered for TestClass for user '))?.[0], + }; + }; + + let calls = await execTest('silly', 'silly', 'debug'); + expect(calls).toEqual({ beforeSave: 'silly', afterSave: 'debug' }); + + calls = await execTest('info', 'warn', 'debug'); + expect(calls).toEqual({ beforeSave: 'warn', afterSave: undefined }); + }); + it('should log cloud function failure', done => { Parse.Cloud.define('aFunction', () => { throw 'it failed!'; diff --git a/spec/DatabaseController.spec.js b/spec/DatabaseController.spec.js index 98103ce6e4..e1b50a5a52 100644 --- a/spec/DatabaseController.spec.js +++ b/spec/DatabaseController.spec.js @@ -1,3 +1,4 @@ +const Config = require('../lib/Config'); const DatabaseController = require('../lib/Controllers/DatabaseController.js'); const validateQuery = DatabaseController._validateQuery; @@ -361,6 +362,259 @@ describe('DatabaseController', function () { done(); }); }); + + describe('enableCollationCaseComparison', () => { + const dummyStorageAdapter = { + find: () => Promise.resolve([]), + watch: () => Promise.resolve(), + getAllClasses: () => Promise.resolve([]), + }; + + beforeEach(() => { + Config.get(Parse.applicationId).schemaCache.clear(); + }); + + it('should force caseInsensitive to false with enableCollationCaseComparison option', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, { + enableCollationCaseComparison: true, + }); + const spy = spyOn(dummyStorageAdapter, 'find'); + spy.and.callThrough(); + await databaseController.find('SomeClass', {}, { caseInsensitive: true }); + expect(spy.calls.all()[0].args[3].caseInsensitive).toEqual(false); + }); + + it('should support caseInsensitive without enableCollationCaseComparison option', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, {}); + const spy = spyOn(dummyStorageAdapter, 'find'); + spy.and.callThrough(); + await databaseController.find('_User', {}, { caseInsensitive: true }); + expect(spy.calls.all()[0].args[3].caseInsensitive).toEqual(true); + }); + + it_only_db('mongo')( + 'should create insensitive indexes without enableCollationCaseComparison', + async () => { + await reconfigureServer({ + databaseURI: 'mongodb://localhost:27017/enableCollationCaseComparisonFalse', + databaseAdapter: undefined, + }); + const user = new Parse.User(); + await user.save({ + username: 'example', + password: 'password', + email: 'example@example.com', + }); + const schemas = await Parse.Schema.all(); + const UserSchema = schemas.find(({ className }) => className === '_User'); + expect(UserSchema.indexes).toEqual({ + _id_: { _id: 1 }, + username_1: { username: 1 }, + case_insensitive_username: { username: 1 }, + case_insensitive_email: { email: 1 }, + email_1: { email: 1 }, + }); + } + ); + + it_only_db('mongo')( + 'should not create insensitive indexes with enableCollationCaseComparison', + async () => { + await reconfigureServer({ + enableCollationCaseComparison: true, + databaseURI: 'mongodb://localhost:27017/enableCollationCaseComparisonTrue', + databaseAdapter: undefined, + }); + const user = new Parse.User(); + await user.save({ + username: 'example', + password: 'password', + email: 'example@example.com', + }); + const schemas = await Parse.Schema.all(); + const UserSchema = schemas.find(({ className }) => className === '_User'); + expect(UserSchema.indexes).toEqual({ + _id_: { _id: 1 }, + username_1: { username: 1 }, + email_1: { email: 1 }, + }); + } + ); + }); + + describe('convertEmailToLowercase', () => { + const dummyStorageAdapter = { + createObject: () => Promise.resolve({ ops: [{}] }), + findOneAndUpdate: () => Promise.resolve({}), + watch: () => Promise.resolve(), + getAllClasses: () => + Promise.resolve([ + { + className: '_User', + fields: { email: 'String' }, + indexes: {}, + classLevelPermissions: { protectedFields: {} }, + }, + ]), + }; + const dates = { + createdAt: { iso: undefined, __type: 'Date' }, + updatedAt: { iso: undefined, __type: 'Date' }, + }; + + it('should not transform email to lower case without convertEmailToLowercase option on create', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, {}); + const spy = spyOn(dummyStorageAdapter, 'createObject'); + spy.and.callThrough(); + await databaseController.create('_User', { + email: 'EXAMPLE@EXAMPLE.COM', + }); + expect(spy.calls.all()[0].args[2]).toEqual({ + email: 'EXAMPLE@EXAMPLE.COM', + ...dates, + }); + }); + + it('should transform email to lower case with convertEmailToLowercase option on create', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, { + convertEmailToLowercase: true, + }); + const spy = spyOn(dummyStorageAdapter, 'createObject'); + spy.and.callThrough(); + await databaseController.create('_User', { + email: 'EXAMPLE@EXAMPLE.COM', + }); + expect(spy.calls.all()[0].args[2]).toEqual({ + email: 'example@example.com', + ...dates, + }); + }); + + it('should not transform email to lower case without convertEmailToLowercase option on update', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, {}); + const spy = spyOn(dummyStorageAdapter, 'findOneAndUpdate'); + spy.and.callThrough(); + await databaseController.update('_User', { id: 'example' }, { email: 'EXAMPLE@EXAMPLE.COM' }); + expect(spy.calls.all()[0].args[3]).toEqual({ + email: 'EXAMPLE@EXAMPLE.COM', + }); + }); + + it('should transform email to lower case with convertEmailToLowercase option on update', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, { + convertEmailToLowercase: true, + }); + const spy = spyOn(dummyStorageAdapter, 'findOneAndUpdate'); + spy.and.callThrough(); + await databaseController.update('_User', { id: 'example' }, { email: 'EXAMPLE@EXAMPLE.COM' }); + expect(spy.calls.all()[0].args[3]).toEqual({ + email: 'example@example.com', + }); + }); + + it('should not find a case insensitive user by email with convertEmailToLowercase', async () => { + await reconfigureServer({ convertEmailToLowercase: true }); + const user = new Parse.User(); + await user.save({ username: 'EXAMPLE', email: 'EXAMPLE@EXAMPLE.COM', password: 'password' }); + + const query = new Parse.Query(Parse.User); + query.equalTo('email', 'EXAMPLE@EXAMPLE.COM'); + const result = await query.find({ useMasterKey: true }); + expect(result.length).toEqual(0); + + const query2 = new Parse.Query(Parse.User); + query2.equalTo('email', 'example@example.com'); + const result2 = await query2.find({ useMasterKey: true }); + expect(result2.length).toEqual(1); + }); + }); + + describe('convertUsernameToLowercase', () => { + const dummyStorageAdapter = { + createObject: () => Promise.resolve({ ops: [{}] }), + findOneAndUpdate: () => Promise.resolve({}), + watch: () => Promise.resolve(), + getAllClasses: () => + Promise.resolve([ + { + className: '_User', + fields: { username: 'String' }, + indexes: {}, + classLevelPermissions: { protectedFields: {} }, + }, + ]), + }; + const dates = { + createdAt: { iso: undefined, __type: 'Date' }, + updatedAt: { iso: undefined, __type: 'Date' }, + }; + + it('should not transform username to lower case without convertUsernameToLowercase option on create', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, {}); + const spy = spyOn(dummyStorageAdapter, 'createObject'); + spy.and.callThrough(); + await databaseController.create('_User', { + username: 'EXAMPLE', + }); + expect(spy.calls.all()[0].args[2]).toEqual({ + username: 'EXAMPLE', + ...dates, + }); + }); + + it('should transform username to lower case with convertUsernameToLowercase option on create', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, { + convertUsernameToLowercase: true, + }); + const spy = spyOn(dummyStorageAdapter, 'createObject'); + spy.and.callThrough(); + await databaseController.create('_User', { + username: 'EXAMPLE', + }); + expect(spy.calls.all()[0].args[2]).toEqual({ + username: 'example', + ...dates, + }); + }); + + it('should not transform username to lower case without convertUsernameToLowercase option on update', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, {}); + const spy = spyOn(dummyStorageAdapter, 'findOneAndUpdate'); + spy.and.callThrough(); + await databaseController.update('_User', { id: 'example' }, { username: 'EXAMPLE' }); + expect(spy.calls.all()[0].args[3]).toEqual({ + username: 'EXAMPLE', + }); + }); + + it('should transform username to lower case with convertUsernameToLowercase option on update', async () => { + const databaseController = new DatabaseController(dummyStorageAdapter, { + convertUsernameToLowercase: true, + }); + const spy = spyOn(dummyStorageAdapter, 'findOneAndUpdate'); + spy.and.callThrough(); + await databaseController.update('_User', { id: 'example' }, { username: 'EXAMPLE' }); + expect(spy.calls.all()[0].args[3]).toEqual({ + username: 'example', + }); + }); + + it('should not find a case insensitive user by username with convertUsernameToLowercase', async () => { + await reconfigureServer({ convertUsernameToLowercase: true }); + const user = new Parse.User(); + await user.save({ username: 'EXAMPLE', password: 'password' }); + + const query = new Parse.Query(Parse.User); + query.equalTo('username', 'EXAMPLE'); + const result = await query.find({ useMasterKey: true }); + expect(result.length).toEqual(0); + + const query2 = new Parse.Query(Parse.User); + query2.equalTo('username', 'example'); + const result2 = await query2.find({ useMasterKey: true }); + expect(result2.length).toEqual(1); + }); + }); }); function buildCLP(pointerNames) { diff --git a/spec/DefinedSchemas.spec.js b/spec/DefinedSchemas.spec.js index 0b1f2a3443..a1c7e3dca5 100644 --- a/spec/DefinedSchemas.spec.js +++ b/spec/DefinedSchemas.spec.js @@ -554,7 +554,7 @@ describe('DefinedSchemas', () => { }); }); - it('should not delete automatically classes', async () => { + it('should not delete classes automatically', async () => { await reconfigureServer({ schema: { definitions: [{ className: '_User' }, { className: 'Test' }] }, }); @@ -631,7 +631,7 @@ describe('DefinedSchemas', () => { const logger = require('../lib/logger').logger; spyOn(DefinedSchemas.prototype, 'wait').and.resolveTo(); spyOn(logger, 'error').and.callThrough(); - spyOn(Parse.Schema, 'all').and.callFake(() => { + spyOn(DefinedSchemas.prototype, 'createDeleteSession').and.callFake(() => { throw error; }); @@ -677,4 +677,33 @@ describe('DefinedSchemas', () => { expect(testSchema.classLevelPermissions.create).toEqual({ requiresAuthentication: true }); expect(logger.error).toHaveBeenCalledTimes(0); }); + + it('should not affect cacheAdapter', async () => { + const server = await reconfigureServer(); + const logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callThrough(); + const migrationOptions = { + definitions: [ + { + className: 'Test', + fields: { aField: { type: 'String' } }, + indexes: { aField: { aField: 1 } }, + classLevelPermissions: { + create: { requiresAuthentication: true }, + }, + }, + ], + }; + + const cacheAdapter = { + get: () => Promise.resolve(null), + put: () => {}, + del: () => {}, + clear: () => {}, + connect: jasmine.createSpy('clear'), + }; + server.config.cacheAdapter = cacheAdapter; + await new DefinedSchemas(migrationOptions, server.config).execute(); + expect(cacheAdapter.connect).not.toHaveBeenCalled(); + }); }); diff --git a/spec/EmailVerificationToken.spec.js b/spec/EmailVerificationToken.spec.js index 50b626de0d..39ad6e5edd 100644 --- a/spec/EmailVerificationToken.spec.js +++ b/spec/EmailVerificationToken.spec.js @@ -1,7 +1,9 @@ 'use strict'; +const Auth = require('../lib/Auth'); const Config = require('../lib/Config'); const request = require('../lib/request'); +const MockEmailAdapterWithOptions = require('./support/MockEmailAdapterWithOptions'); describe('Email Verification Token Expiration: ', () => { it('show the invalid verification link page, if the user clicks on the verify email link after the email verify token expires', done => { @@ -125,6 +127,7 @@ describe('Email Verification Token Expiration: ', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { request({ url: sendEmailOptions.link, @@ -166,6 +169,7 @@ describe('Email Verification Token Expiration: ', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { request({ url: sendEmailOptions.link, @@ -213,6 +217,7 @@ describe('Email Verification Token Expiration: ', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { request({ url: sendEmailOptions.link, @@ -262,9 +267,14 @@ describe('Email Verification Token Expiration: ', () => { }) .then(() => { const config = Config.get('test'); - return config.database.find('_User', { - username: 'sets_email_verify_token_expires_at', - }); + return config.database.find( + '_User', + { + username: 'sets_email_verify_token_expires_at', + }, + {}, + Auth.maintenance(config) + ); }) .then(results => { expect(results.length).toBe(1); @@ -282,6 +292,223 @@ describe('Email Verification Token Expiration: ', () => { }); }); + it('can conditionally send emails', async () => { + let sendEmailOptions; + const emailAdapter = { + sendVerificationEmail: options => { + sendEmailOptions = options; + }, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + const verifyUserEmails = { + method(req) { + expect(Object.keys(req)).toEqual(['original', 'object', 'master', 'ip', 'installationId']); + return false; + }, + }; + const verifySpy = spyOn(verifyUserEmails, 'method').and.callThrough(); + await reconfigureServer({ + appName: 'emailVerifyToken', + verifyUserEmails: verifyUserEmails.method, + emailAdapter: emailAdapter, + emailVerifyTokenValidityDuration: 5, // 5 seconds + publicServerURL: 'http://localhost:8378/1', + }); + const beforeSave = { + method(req) { + req.object.set('emailVerified', true); + }, + }; + const saveSpy = spyOn(beforeSave, 'method').and.callThrough(); + const emailSpy = spyOn(emailAdapter, 'sendVerificationEmail').and.callThrough(); + Parse.Cloud.beforeSave(Parse.User, beforeSave.method); + const user = new Parse.User(); + user.setUsername('sets_email_verify_token_expires_at'); + user.setPassword('expiringToken'); + user.set('email', 'user@example.com'); + await user.signUp(); + + const config = Config.get('test'); + const results = await config.database.find( + '_User', + { + username: 'sets_email_verify_token_expires_at', + }, + {}, + Auth.maintenance(config) + ); + + expect(results.length).toBe(1); + const user_data = results[0]; + expect(typeof user_data).toBe('object'); + expect(user_data.emailVerified).toEqual(true); + expect(user_data._email_verify_token).toBeUndefined(); + expect(user_data._email_verify_token_expires_at).toBeUndefined(); + expect(emailSpy).not.toHaveBeenCalled(); + expect(saveSpy).toHaveBeenCalled(); + expect(sendEmailOptions).toBeUndefined(); + expect(verifySpy).toHaveBeenCalled(); + }); + + it('can conditionally send emails and allow conditional login', async () => { + let sendEmailOptions; + const emailAdapter = { + sendVerificationEmail: options => { + sendEmailOptions = options; + }, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + const verifyUserEmails = { + method(req) { + expect(Object.keys(req)).toEqual(['original', 'object', 'master', 'ip', 'installationId']); + if (req.object.get('username') === 'no_email') { + return false; + } + return true; + }, + }; + const verifySpy = spyOn(verifyUserEmails, 'method').and.callThrough(); + await reconfigureServer({ + appName: 'emailVerifyToken', + verifyUserEmails: verifyUserEmails.method, + preventLoginWithUnverifiedEmail: verifyUserEmails.method, + emailAdapter: emailAdapter, + emailVerifyTokenValidityDuration: 5, // 5 seconds + publicServerURL: 'http://localhost:8378/1', + }); + const user = new Parse.User(); + user.setUsername('no_email'); + user.setPassword('expiringToken'); + user.set('email', 'user@example.com'); + await user.signUp(); + expect(sendEmailOptions).toBeUndefined(); + expect(user.getSessionToken()).toBeDefined(); + expect(verifySpy).toHaveBeenCalledTimes(2); + const user2 = new Parse.User(); + user2.setUsername('email'); + user2.setPassword('expiringToken'); + user2.set('email', 'user2@example.com'); + await user2.signUp(); + await jasmine.timeout(); + expect(user2.getSessionToken()).toBeUndefined(); + expect(sendEmailOptions).toBeDefined(); + expect(verifySpy).toHaveBeenCalledTimes(5); + }); + + it('can conditionally send user email verification', async () => { + const emailAdapter = { + sendVerificationEmail: () => {}, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + const sendVerificationEmail = { + method(req) { + expect(req.user).toBeDefined(); + expect(req.master).toBeDefined(); + return false; + }, + }; + const sendSpy = spyOn(sendVerificationEmail, 'method').and.callThrough(); + await reconfigureServer({ + appName: 'emailVerifyToken', + verifyUserEmails: true, + emailAdapter: emailAdapter, + emailVerifyTokenValidityDuration: 5, // 5 seconds + publicServerURL: 'http://localhost:8378/1', + sendUserEmailVerification: sendVerificationEmail.method, + }); + const emailSpy = spyOn(emailAdapter, 'sendVerificationEmail').and.callThrough(); + const newUser = new Parse.User(); + newUser.setUsername('unsets_email_verify_token_expires_at'); + newUser.setPassword('expiringToken'); + newUser.set('email', 'user@example.com'); + await newUser.signUp(); + await Parse.User.requestEmailVerification('user@example.com'); + await jasmine.timeout(); + expect(sendSpy).toHaveBeenCalledTimes(2); + expect(emailSpy).toHaveBeenCalledTimes(0); + }); + + it('provides full user object in email verification function on email and username change', async () => { + const emailAdapter = { + sendVerificationEmail: () => {}, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + const sendVerificationEmail = { + method(req) { + expect(req.user).toBeDefined(); + expect(req.user.id).toBeDefined(); + expect(req.user.get('createdAt')).toBeDefined(); + expect(req.user.get('updatedAt')).toBeDefined(); + expect(req.master).toBeDefined(); + return false; + }, + }; + await reconfigureServer({ + appName: 'emailVerifyToken', + verifyUserEmails: true, + emailAdapter: emailAdapter, + emailVerifyTokenValidityDuration: 5, + publicServerURL: 'http://localhost:8378/1', + sendUserEmailVerification: sendVerificationEmail.method, + }); + const user = new Parse.User(); + user.setPassword('password'); + user.setUsername('new@example.com'); + user.setEmail('user@example.com'); + await user.save(null, { useMasterKey: true }); + + // Update email and username + user.setUsername('new@example.com'); + user.setEmail('new@example.com'); + await user.save(null, { useMasterKey: true }); + }); + + it('beforeSave options do not change existing behaviour', async () => { + let sendEmailOptions; + const emailAdapter = { + sendVerificationEmail: options => { + sendEmailOptions = options; + }, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + await reconfigureServer({ + appName: 'emailVerifyToken', + verifyUserEmails: true, + emailAdapter: emailAdapter, + emailVerifyTokenValidityDuration: 5, // 5 seconds + publicServerURL: 'http://localhost:8378/1', + }); + const emailSpy = spyOn(emailAdapter, 'sendVerificationEmail').and.callThrough(); + const newUser = new Parse.User(); + newUser.setUsername('unsets_email_verify_token_expires_at'); + newUser.setPassword('expiringToken'); + newUser.set('email', 'user@parse.com'); + await newUser.signUp(); + await jasmine.timeout(); + const response = await request({ + url: sendEmailOptions.link, + followRedirects: false, + }); + expect(response.status).toEqual(302); + const config = Config.get('test'); + const results = await config.database.find('_User', { + username: 'unsets_email_verify_token_expires_at', + }); + + expect(results.length).toBe(1); + const user = results[0]; + expect(typeof user).toBe('object'); + expect(user.emailVerified).toEqual(true); + expect(typeof user._email_verify_token).toBe('undefined'); + expect(typeof user._email_verify_token_expires_at).toBe('undefined'); + expect(emailSpy).toHaveBeenCalled(); + }); + it('unsets the _email_verify_token_expires_at and _email_verify_token fields in the User class if email verification is successful', done => { const user = new Parse.User(); let sendEmailOptions; @@ -305,6 +532,7 @@ describe('Email Verification Token Expiration: ', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { request({ url: sendEmailOptions.link, @@ -364,6 +592,7 @@ describe('Email Verification Token Expiration: ', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { return request({ url: sendEmailOptions.link, @@ -499,7 +728,12 @@ describe('Email Verification Token Expiration: ', () => { .then(() => { const config = Config.get('test'); return config.database - .find('_User', { username: 'newEmailVerifyTokenOnEmailReset' }) + .find( + '_User', + { username: 'newEmailVerifyTokenOnEmailReset' }, + {}, + Auth.maintenance(config) + ) .then(results => { return results[0]; }); @@ -576,13 +810,16 @@ describe('Email Verification Token Expiration: ', () => { }) .then(response => { expect(response.status).toBe(200); + }) + .then(() => jasmine.timeout()) + .then(() => { expect(sendVerificationEmailCallCount).toBe(2); expect(sendEmailOptions).toBeDefined(); // query for this user again const config = Config.get('test'); return config.database - .find('_User', { username: 'resends_verification_token' }) + .find('_User', { username: 'resends_verification_token' }, {}, Auth.maintenance(config)) .then(results => { return results[0]; }); @@ -599,11 +836,47 @@ describe('Email Verification Token Expiration: ', () => { done(); }) .catch(error => { + console.log(error); jfail(error); done(); }); }); + it('provides function arguments in verifyUserEmails on verificationEmailRequest', async () => { + const user = new Parse.User(); + user.setUsername('user'); + user.setPassword('pass'); + user.set('email', 'test@example.com'); + await user.signUp(); + + const verifyUserEmails = { + method: async (params) => { + expect(params.object).toBeInstanceOf(Parse.User); + expect(params.ip).toBeDefined(); + expect(params.master).toBeDefined(); + expect(params.installationId).toBeDefined(); + expect(params.resendRequest).toBeTrue(); + return true; + }, + }; + const verifyUserEmailsSpy = spyOn(verifyUserEmails, 'method').and.callThrough(); + await reconfigureServer({ + appName: 'test', + publicServerURL: 'http://localhost:1337/1', + verifyUserEmails: verifyUserEmails.method, + preventLoginWithUnverifiedEmail: verifyUserEmails.method, + preventSignupWithUnverifiedEmail: true, + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + }); + + await expectAsync(Parse.User.requestEmailVerification('test@example.com')).toBeResolved(); + expect(verifyUserEmailsSpy).toHaveBeenCalledTimes(1); + }); + it('should throw with invalid emailVerifyTokenReuseIfValid', async done => { const sendEmailOptions = []; const emailAdapter = { @@ -671,7 +944,7 @@ describe('Email Verification Token Expiration: ', () => { const config = Config.get('test'); const [userBeforeRequest] = await config.database.find('_User', { username: 'resends_verification_token', - }); + }, {}, Auth.maintenance(config)); // store this user before we make our email request expect(sendVerificationEmailCallCount).toBe(1); await new Promise(resolve => { @@ -691,20 +964,21 @@ describe('Email Verification Token Expiration: ', () => { 'Content-Type': 'application/json', }, }); + await jasmine.timeout(); expect(response.status).toBe(200); expect(sendVerificationEmailCallCount).toBe(2); expect(sendEmailOptions).toBeDefined(); const [userAfterRequest] = await config.database.find('_User', { username: 'resends_verification_token', - }); + }, {}, Auth.maintenance(config)); - // verify that our token & expiration has been changed for this new request + // Verify that token & expiration haven't been changed for this new request expect(typeof userAfterRequest).toBe('object'); + expect(userBeforeRequest._email_verify_token).toBeDefined(); expect(userBeforeRequest._email_verify_token).toEqual(userAfterRequest._email_verify_token); - expect(userBeforeRequest._email_verify_token_expires_at).toEqual( - userAfterRequest._email_verify_token_expires_at - ); + expect(userBeforeRequest._email_verify_token_expires_at).toBeDefined(); + expect(userBeforeRequest._email_verify_token_expires_at).toEqual(userAfterRequest._email_verify_token_expires_at); done(); }); @@ -733,6 +1007,7 @@ describe('Email Verification Token Expiration: ', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { return request({ url: sendEmailOptions.link, @@ -971,6 +1246,7 @@ describe('Email Verification Token Expiration: ', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { request({ url: sendEmailOptions.link, diff --git a/spec/FilesController.spec.js b/spec/FilesController.spec.js index 8fee5aca2f..a16451f3ef 100644 --- a/spec/FilesController.spec.js +++ b/spec/FilesController.spec.js @@ -55,6 +55,8 @@ describe('FilesController', () => { const config = Config.get(Parse.applicationId); expect(config.database.adapter._mongoOptions.retryWrites).toBeTrue(); expect(config.filesController.adapter._mongoOptions.retryWrites).toBeTrue(); + expect(config.filesController.adapter._mongoOptions.enableSchemaHooks).toBeUndefined(); + expect(config.filesController.adapter._mongoOptions.schemaCacheTtl).toBeUndefined(); }); it('should create a server log on failure', done => { diff --git a/spec/GridFSBucketStorageAdapter.spec.js b/spec/GridFSBucketStorageAdapter.spec.js index 419bfdb98d..7e9c84a59e 100644 --- a/spec/GridFSBucketStorageAdapter.spec.js +++ b/spec/GridFSBucketStorageAdapter.spec.js @@ -20,6 +20,22 @@ describe_only_db('mongo')('GridFSBucket', () => { await db.dropDatabase(); }); + it('should connect to mongo with the supported database options', async () => { + const databaseURI = 'mongodb://localhost:27017/parse'; + const gfsAdapter = new GridFSBucketAdapter(databaseURI, { + retryWrites: true, + // these are not supported by the mongo client + enableSchemaHooks: true, + schemaCacheTtl: 5000, + maxTimeMS: 30000, + }); + + const db = await gfsAdapter._connect(); + const status = await db.admin().serverStatus(); + expect(status.connections.current > 0).toEqual(true); + expect(db.options?.retryWrites).toEqual(true); + }); + it('should save an encrypted file that can only be decrypted by a GridFS adapter with the encryptionKey', async () => { const unencryptedAdapter = new GridFSBucketAdapter(databaseURI); const encryptedAdapter = new GridFSBucketAdapter( diff --git a/spec/HTTPRequest.spec.js b/spec/HTTPRequest.spec.js index f218ff3c91..1321ca2627 100644 --- a/spec/HTTPRequest.spec.js +++ b/spec/HTTPRequest.spec.js @@ -1,7 +1,7 @@ 'use strict'; -const httpRequest = require('../lib/cloud-code/httpRequest'), - HTTPResponse = require('../lib/cloud-code/HTTPResponse').default, +const httpRequest = require('../lib/request'), + HTTPResponse = require('../lib/request').HTTPResponse, bodyParser = require('body-parser'), express = require('express'); diff --git a/spec/Idempotency.spec.js b/spec/Idempotency.spec.js index a45d19343c..813923b1ff 100644 --- a/spec/Idempotency.spec.js +++ b/spec/Idempotency.spec.js @@ -45,10 +45,6 @@ describe('Idempotency', () => { }); }); - afterAll(() => { - jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 10000; - }); - // Tests it('should enforce idempotency for cloud code function', async () => { let counter = 0; diff --git a/spec/Middlewares.spec.js b/spec/Middlewares.spec.js index 2c380152ba..af547ec77a 100644 --- a/spec/Middlewares.spec.js +++ b/spec/Middlewares.spec.js @@ -1,11 +1,19 @@ const middlewares = require('../lib/middlewares'); const AppCache = require('../lib/cache').AppCache; +const { BlockList } = require('net'); + +const AppCachePut = (appId, config) => + AppCache.put(appId, { + ...config, + maintenanceKeyIpsStore: new Map(), + masterKeyIpsStore: new Map(), + }); describe('middlewares', () => { let fakeReq, fakeRes; - beforeEach(() => { fakeReq = { + ip: '127.0.0.1', originalUrl: 'http://example.com/parse/', url: 'http://example.com/', body: { @@ -17,7 +25,7 @@ describe('middlewares', () => { }, }; fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status']); - AppCache.put(fakeReq.body._ApplicationId, {}); + AppCachePut(fakeReq.body._ApplicationId, {}); }); afterEach(() => { @@ -25,6 +33,9 @@ describe('middlewares', () => { }); it('should use _ContentType if provided', done => { + AppCachePut(fakeReq.body._ApplicationId, { + masterKeyIps: ['127.0.0.1'], + }); expect(fakeReq.headers['content-type']).toEqual(undefined); const contentType = 'image/jpeg'; fakeReq.body._ContentType = contentType; @@ -36,7 +47,7 @@ describe('middlewares', () => { }); it('should give invalid response when keys are configured but no key supplied', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', restAPIKey: 'restAPIKey', }); @@ -45,7 +56,7 @@ describe('middlewares', () => { }); it('should give invalid response when keys are configured but supplied key is incorrect', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', restAPIKey: 'restAPIKey', }); @@ -55,7 +66,7 @@ describe('middlewares', () => { }); it('should give invalid response when keys are configured but different key is supplied', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', restAPIKey: 'restAPIKey', }); @@ -65,7 +76,7 @@ describe('middlewares', () => { }); it('should succeed when any one of the configured keys supplied', done => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { clientKey: 'clientKey', masterKey: 'masterKey', restAPIKey: 'restAPIKey', @@ -78,7 +89,7 @@ describe('middlewares', () => { }); it('should succeed when client key supplied but empty', done => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { clientKey: '', masterKey: 'masterKey', restAPIKey: 'restAPIKey', @@ -91,7 +102,7 @@ describe('middlewares', () => { }); it('should succeed when no keys are configured and none supplied', done => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', }); middlewares.handleParseHeaders(fakeReq, fakeRes, () => { @@ -117,10 +128,12 @@ describe('middlewares', () => { const otherKeys = BodyKeys.filter( otherKey => otherKey !== infoKey && otherKey !== 'javascriptKey' ); - it(`it should pull ${bodyKey} into req.info`, done => { + AppCachePut(fakeReq.body._ApplicationId, { + masterKeyIps: ['0.0.0.0/0'], + }); + fakeReq.ip = '127.0.0.1'; fakeReq.body[bodyKey] = keyValue; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { expect(fakeReq.body[bodyKey]).toEqual(undefined); expect(fakeReq.info[infoKey]).toEqual(keyValue); @@ -134,161 +147,81 @@ describe('middlewares', () => { }); }); - it('should not succeed if the ip does not belong to masterKeyIps list', () => { - AppCache.put(fakeReq.body._ApplicationId, { + it('should not succeed and log if the ip does not belong to masterKeyIps list', async () => { + const logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callFake(() => {}); + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], + masterKeyIps: ['10.0.0.1'], }); - fakeReq.ip = 'ip3'; + fakeReq.ip = '127.0.0.1'; fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes); - expect(fakeRes.status).toHaveBeenCalledWith(403); - }); - it('should succeed if the ip does belong to masterKeyIps list', done => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], - }); - fakeReq.ip = 'ip1'; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); - }); + let error; - it('should not succeed if the connection.remoteAddress does not belong to masterKeyIps list', () => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], - }); - fakeReq.connection = { remoteAddress: 'ip3' }; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes); - expect(fakeRes.status).toHaveBeenCalledWith(403); - }); + try { + await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve)); + } catch (err) { + error = err; + } - it('should succeed if the connection.remoteAddress does belong to masterKeyIps list', done => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], - }); - fakeReq.connection = { remoteAddress: 'ip1' }; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); + expect(error).toBeDefined(); + expect(error.message).toEqual(`unauthorized`); + expect(logger.error).toHaveBeenCalledWith( + `Request using master key rejected as the request IP address '127.0.0.1' is not set in Parse Server option 'masterKeyIps'.` + ); }); - it('should not succeed if the socket.remoteAddress does not belong to masterKeyIps list', () => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], + it('should not succeed and log if the ip does not belong to maintenanceKeyIps list', async () => { + const logger = require('../lib/logger').logger; + spyOn(logger, 'error').and.callFake(() => {}); + AppCachePut(fakeReq.body._ApplicationId, { + maintenanceKey: 'masterKey', + maintenanceKeyIps: ['10.0.0.0', '10.0.0.1'], }); - fakeReq.socket = { remoteAddress: 'ip3' }; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes); - expect(fakeRes.status).toHaveBeenCalledWith(403); - }); + fakeReq.ip = '10.0.0.2'; + fakeReq.headers['x-parse-maintenance-key'] = 'masterKey'; - it('should succeed if the socket.remoteAddress does belong to masterKeyIps list', done => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], - }); - fakeReq.socket = { remoteAddress: 'ip1' }; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); - }); + let error; - it('should not succeed if the connection.socket.remoteAddress does not belong to masterKeyIps list', () => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], - }); - fakeReq.connection = { socket: { remoteAddress: 'ip3' } }; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes); - expect(fakeRes.status).toHaveBeenCalledWith(403); - }); + try { + await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve)); + } catch (err) { + error = err; + } - it('should succeed if the connection.socket.remoteAddress does belong to masterKeyIps list', done => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1', 'ip2'], - }); - fakeReq.connection = { socket: { remoteAddress: 'ip1' } }; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); - }); - - it('should allow any ip to use masterKey if masterKeyIps is empty', done => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: [], - }); - fakeReq.ip = 'ip1'; - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); - }); - - it('should succeed if xff header does belong to masterKeyIps', done => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1'], - }); - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - fakeReq.headers['x-forwarded-for'] = 'ip1, ip2, ip3'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); + expect(error).toBeDefined(); + expect(error.message).toEqual(`unauthorized`); + expect(logger.error).toHaveBeenCalledWith( + `Request using maintenance key rejected as the request IP address '10.0.0.2' is not set in Parse Server option 'maintenanceKeyIps'.` + ); }); - it('should succeed if xff header with one ip does belong to masterKeyIps', done => { - AppCache.put(fakeReq.body._ApplicationId, { + it('should succeed if the ip does belong to masterKeyIps list', async () => { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', - masterKeyIps: ['ip1'], + masterKeyIps: ['10.0.0.1'], }); + fakeReq.ip = '10.0.0.1'; fakeReq.headers['x-parse-master-key'] = 'masterKey'; - fakeReq.headers['x-forwarded-for'] = 'ip1'; - middlewares.handleParseHeaders(fakeReq, fakeRes, () => { - expect(fakeRes.status).not.toHaveBeenCalled(); - done(); - }); + await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve)); + expect(fakeReq.auth.isMaster).toBe(true); }); - it('should not succeed if xff header does not belong to masterKeyIps', () => { - AppCache.put(fakeReq.body._ApplicationId, { + it('should allow any ip to use masterKey if masterKeyIps is empty', async () => { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', - masterKeyIps: ['ip4'], + masterKeyIps: ['0.0.0.0/0'], }); + fakeReq.ip = '10.0.0.1'; fakeReq.headers['x-parse-master-key'] = 'masterKey'; - fakeReq.headers['x-forwarded-for'] = 'ip1, ip2, ip3'; - middlewares.handleParseHeaders(fakeReq, fakeRes); - expect(fakeRes.status).toHaveBeenCalledWith(403); + await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve)); + expect(fakeReq.auth.isMaster).toBe(true); }); - it('should not succeed if xff header is empty and masterKeyIps is set', () => { - AppCache.put(fakeReq.body._ApplicationId, { - masterKey: 'masterKey', - masterKeyIps: ['ip1'], - }); - fakeReq.headers['x-parse-master-key'] = 'masterKey'; - fakeReq.headers['x-forwarded-for'] = ''; - middlewares.handleParseHeaders(fakeReq, fakeRes); - expect(fakeRes.status).toHaveBeenCalledWith(403); + it('can set trust proxy', async () => { + const server = await reconfigureServer({ trustProxy: 1 }); + expect(server.app.parent.settings['trust proxy']).toBe(1); }); it('should properly expose the headers', () => { @@ -307,7 +240,7 @@ describe('middlewares', () => { }); it('should set default Access-Control-Allow-Headers if allowHeaders are empty', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { allowHeaders: undefined, }); const headers = {}; @@ -320,7 +253,7 @@ describe('middlewares', () => { allowCrossDomain(fakeReq, res, () => {}); expect(headers['Access-Control-Allow-Headers']).toContain(middlewares.DEFAULT_ALLOWED_HEADERS); - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { allowHeaders: [], }); allowCrossDomain(fakeReq, res, () => {}); @@ -328,7 +261,7 @@ describe('middlewares', () => { }); it('should append custom headers to Access-Control-Allow-Headers if allowHeaders provided', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { allowHeaders: ['Header-1', 'Header-2'], }); const headers = {}; @@ -344,7 +277,7 @@ describe('middlewares', () => { }); it('should set default Access-Control-Allow-Origin if allowOrigin is empty', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { allowOrigin: undefined, }); const headers = {}; @@ -359,7 +292,7 @@ describe('middlewares', () => { }); it('should set custom origin to Access-Control-Allow-Origin if allowOrigin is provided', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { allowOrigin: 'https://parseplatform.org/', }); const headers = {}; @@ -373,8 +306,37 @@ describe('middlewares', () => { expect(headers['Access-Control-Allow-Origin']).toEqual('https://parseplatform.org/'); }); - it('should use user provided on field userFromJWT', done => { + it('should support multiple origins if several are defined in allowOrigin as an array', () => { AppCache.put(fakeReq.body._ApplicationId, { + allowOrigin: ['https://a.com', 'https://b.com', 'https://c.com'], + }); + const headers = {}; + const res = { + header: (key, value) => { + headers[key] = value; + }, + }; + const allowCrossDomain = middlewares.allowCrossDomain(fakeReq.body._ApplicationId); + // Test with the first domain + fakeReq.headers.origin = 'https://a.com'; + allowCrossDomain(fakeReq, res, () => {}); + expect(headers['Access-Control-Allow-Origin']).toEqual('https://a.com'); + // Test with the second domain + fakeReq.headers.origin = 'https://b.com'; + allowCrossDomain(fakeReq, res, () => {}); + expect(headers['Access-Control-Allow-Origin']).toEqual('https://b.com'); + // Test with the third domain + fakeReq.headers.origin = 'https://c.com'; + allowCrossDomain(fakeReq, res, () => {}); + expect(headers['Access-Control-Allow-Origin']).toEqual('https://c.com'); + // Test with an unauthorized domain + fakeReq.headers.origin = 'https://unauthorized.com'; + allowCrossDomain(fakeReq, res, () => {}); + expect(headers['Access-Control-Allow-Origin']).toEqual('https://a.com'); + }); + + it('should use user provided on field userFromJWT', done => { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', }); fakeReq.userFromJWT = 'fake-user'; @@ -385,11 +347,87 @@ describe('middlewares', () => { }); it('should give invalid response when upload file without x-parse-application-id in header', () => { - AppCache.put(fakeReq.body._ApplicationId, { + AppCachePut(fakeReq.body._ApplicationId, { masterKey: 'masterKey', }); fakeReq.body = Buffer.from('fake-file'); middlewares.handleParseHeaders(fakeReq, fakeRes); expect(fakeRes.status).toHaveBeenCalledWith(403); }); + + it('should match address', () => { + const ipv6 = '2001:0db8:85a3:0000:0000:8a2e:0370:7334'; + const anotherIpv6 = '::ffff:101.10.0.1'; + const ipv4 = '192.168.0.101'; + const localhostV6 = '::1'; + const localhostV62 = '::ffff:127.0.0.1'; + const localhostV4 = '127.0.0.1'; + + const v6 = [ipv6, anotherIpv6]; + v6.forEach(ip => { + expect(middlewares.checkIp(ip, ['::/0'], new Map())).toBe(true); + expect(middlewares.checkIp(ip, ['::'], new Map())).toBe(true); + expect(middlewares.checkIp(ip, ['0.0.0.0'], new Map())).toBe(false); + expect(middlewares.checkIp(ip, ['0.0.0.0/0'], new Map())).toBe(false); + expect(middlewares.checkIp(ip, ['123.123.123.123'], new Map())).toBe(false); + }); + + expect(middlewares.checkIp(ipv6, [anotherIpv6], new Map())).toBe(false); + expect(middlewares.checkIp(ipv6, [ipv6], new Map())).toBe(true); + expect(middlewares.checkIp(ipv6, ['2001:db8:85a3:0:0:8a2e:0:0/100'], new Map())).toBe(true); + + expect(middlewares.checkIp(ipv4, ['::'], new Map())).toBe(false); + expect(middlewares.checkIp(ipv4, ['::/0'], new Map())).toBe(false); + expect(middlewares.checkIp(ipv4, ['0.0.0.0'], new Map())).toBe(true); + expect(middlewares.checkIp(ipv4, ['0.0.0.0/0'], new Map())).toBe(true); + expect(middlewares.checkIp(ipv4, ['123.123.123.123'], new Map())).toBe(false); + expect(middlewares.checkIp(ipv4, [ipv4], new Map())).toBe(true); + expect(middlewares.checkIp(ipv4, ['192.168.0.0/24'], new Map())).toBe(true); + + expect(middlewares.checkIp(localhostV4, ['::1'], new Map())).toBe(false); + expect(middlewares.checkIp(localhostV6, ['::1'], new Map())).toBe(true); + // ::ffff:127.0.0.1 is a padded ipv4 address but not ::1 + expect(middlewares.checkIp(localhostV62, ['::1'], new Map())).toBe(false); + // ::ffff:127.0.0.1 is a padded ipv4 address and is a match for 127.0.0.1 + expect(middlewares.checkIp(localhostV62, ['127.0.0.1'], new Map())).toBe(true); + }); + + it('should match address with cache', () => { + const ipv6 = '2001:0db8:85a3:0000:0000:8a2e:0370:7334'; + const cache1 = new Map(); + const spyBlockListCheck = spyOn(BlockList.prototype, 'check').and.callThrough(); + expect(middlewares.checkIp(ipv6, ['::'], cache1)).toBe(true); + expect(cache1.get('2001:0db8:85a3:0000:0000:8a2e:0370:7334')).toBe(undefined); + expect(cache1.get('allowAllIpv6')).toBe(true); + expect(spyBlockListCheck).toHaveBeenCalledTimes(0); + + const cache2 = new Map(); + expect(middlewares.checkIp('::1', ['::1'], cache2)).toBe(true); + expect(cache2.get('::1')).toBe(true); + expect(spyBlockListCheck).toHaveBeenCalledTimes(1); + expect(middlewares.checkIp('::1', ['::1'], cache2)).toBe(true); + expect(spyBlockListCheck).toHaveBeenCalledTimes(1); + spyBlockListCheck.calls.reset(); + + const cache3 = new Map(); + expect(middlewares.checkIp('127.0.0.1', ['127.0.0.1'], cache3)).toBe(true); + expect(cache3.get('127.0.0.1')).toBe(true); + expect(spyBlockListCheck).toHaveBeenCalledTimes(1); + expect(middlewares.checkIp('127.0.0.1', ['127.0.0.1'], cache3)).toBe(true); + expect(spyBlockListCheck).toHaveBeenCalledTimes(1); + spyBlockListCheck.calls.reset(); + + const cache4 = new Map(); + const ranges = ['127.0.0.1', '192.168.0.0/24']; + // should not cache negative match + expect(middlewares.checkIp('123.123.123.123', ranges, cache4)).toBe(false); + expect(cache4.get('123.123.123.123')).toBe(undefined); + expect(spyBlockListCheck).toHaveBeenCalledTimes(1); + spyBlockListCheck.calls.reset(); + + // should not cache cidr + expect(middlewares.checkIp('192.168.0.101', ranges, cache4)).toBe(true); + expect(cache4.get('192.168.0.101')).toBe(undefined); + expect(spyBlockListCheck).toHaveBeenCalledTimes(1); + }); }); diff --git a/spec/MongoStorageAdapter.spec.js b/spec/MongoStorageAdapter.spec.js index f78caa2608..e7bbfe0cd8 100644 --- a/spec/MongoStorageAdapter.spec.js +++ b/spec/MongoStorageAdapter.spec.js @@ -6,7 +6,6 @@ const databaseURI = 'mongodb://localhost:27017/parseServerMongoAdapterTestDataba const request = require('../lib/request'); const Config = require('../lib/Config'); const TestUtils = require('../lib/TestUtils'); -const semver = require('semver'); const fakeClient = { s: { options: { dbName: null } }, @@ -213,6 +212,89 @@ describe_only_db('mongo')('MongoStorageAdapter', () => { }); }); + it('handles nested dates', async () => { + await new Parse.Object('MyClass', { + foo: { + test: { + date: new Date(), + }, + }, + bar: { + date: new Date(), + }, + date: new Date(), + }).save(); + const adapter = Config.get(Parse.applicationId).database.adapter; + const [object] = await adapter._rawFind('MyClass', {}); + expect(object.date instanceof Date).toBeTrue(); + expect(object.bar.date instanceof Date).toBeTrue(); + expect(object.foo.test.date instanceof Date).toBeTrue(); + }); + + it('handles nested dates in array ', async () => { + await new Parse.Object('MyClass', { + foo: { + test: { + date: [new Date()], + }, + }, + bar: { + date: [new Date()], + }, + date: [new Date()], + }).save(); + const adapter = Config.get(Parse.applicationId).database.adapter; + const [object] = await adapter._rawFind('MyClass', {}); + expect(object.date[0] instanceof Date).toBeTrue(); + expect(object.bar.date[0] instanceof Date).toBeTrue(); + expect(object.foo.test.date[0] instanceof Date).toBeTrue(); + const obj = await new Parse.Query('MyClass').first({ useMasterKey: true }); + expect(obj.get('date')[0] instanceof Date).toBeTrue(); + expect(obj.get('bar').date[0] instanceof Date).toBeTrue(); + expect(obj.get('foo').test.date[0] instanceof Date).toBeTrue(); + }); + + it('upserts with $setOnInsert', async () => { + const uuid = require('uuid'); + const uuid1 = uuid.v4(); + const uuid2 = uuid.v4(); + const schema = { + className: 'MyClass', + fields: { + x: { type: 'Number' }, + count: { type: 'Number' }, + }, + classLevelPermissions: {}, + }; + + const myClassSchema = new Parse.Schema(schema.className); + myClassSchema.setCLP(schema.classLevelPermissions); + await myClassSchema.save(); + + const query = { + x: 1, + }; + const update = { + objectId: { + __op: 'SetOnInsert', + amount: uuid1, + }, + count: { + __op: 'Increment', + amount: 1, + }, + }; + await Parse.Server.database.update('MyClass', query, update, { upsert: true }); + update.objectId.amount = uuid2; + await Parse.Server.database.update('MyClass', query, update, { upsert: true }); + + const res = await Parse.Server.database.find(schema.className, {}, {}); + expect(res.length).toBe(1); + expect(res[0].objectId).toBe(uuid1); + expect(res[0].count).toBe(2); + expect(res[0].x).toBe(1); + }); + it('handles updating a single object with array, object date', done => { const adapter = new MongoStorageAdapter({ uri: databaseURI }); @@ -401,11 +483,7 @@ describe_only_db('mongo')('MongoStorageAdapter', () => { expect(schemaAfterDeletion.fields.test).toBeUndefined(); }); - if ( - semver.satisfies(process.env.MONGODB_VERSION, '>=4.0.4') && - process.env.MONGODB_TOPOLOGY === 'replicaset' && - process.env.MONGODB_STORAGE_ENGINE === 'wiredTiger' - ) { + if (process.env.MONGODB_TOPOLOGY === 'replicaset') { describe('transactions', () => { const headers = { 'Content-Type': 'application/json', diff --git a/spec/PagesRouter.spec.js b/spec/PagesRouter.spec.js index e50144f1fe..5f86922b08 100644 --- a/spec/PagesRouter.spec.js +++ b/spec/PagesRouter.spec.js @@ -749,6 +749,7 @@ describe('Pages Router', () => { user.setPassword('examplePassword'); user.set('email', 'mail@example.com'); await user.signUp(); + await jasmine.timeout(); const link = sendVerificationEmail.calls.all()[0].args[0].link; const linkWithLocale = new URL(link); @@ -777,6 +778,7 @@ describe('Pages Router', () => { user.setPassword('examplePassword'); user.set('email', 'mail@example.com'); await user.signUp(); + await jasmine.timeout(); const link = sendVerificationEmail.calls.all()[0].args[0].link; const linkWithLocale = new URL(link); @@ -830,6 +832,7 @@ describe('Pages Router', () => { user.setPassword('examplePassword'); user.set('email', 'mail@example.com'); await user.signUp(); + await jasmine.timeout(); const link = sendVerificationEmail.calls.all()[0].args[0].link; const linkWithLocale = new URL(link); @@ -846,6 +849,8 @@ describe('Pages Router', () => { const locale = linkResponse.headers['x-parse-page-param-locale']; const username = linkResponse.headers['x-parse-page-param-username']; const publicServerUrl = linkResponse.headers['x-parse-page-param-publicserverurl']; + await jasmine.timeout(); + const invalidVerificationPagePath = pageResponse.calls.all()[0].args[0]; expect(appId).toBeDefined(); expect(locale).toBe(exampleLocale); @@ -1190,6 +1195,7 @@ describe('Pages Router', () => { user.setPassword('examplePassword'); user.set('email', 'mail@example.com'); await user.signUp(); + await jasmine.timeout(); const link = sendVerificationEmail.calls.all()[0].args[0].link; const linkResponse = await request({ @@ -1197,7 +1203,6 @@ describe('Pages Router', () => { followRedirects: false, }); expect(linkResponse.status).toBe(200); - const pagePath = pageResponse.calls.all()[0].args[0]; expect(pagePath).toMatch(new RegExp(`\/${pages.emailVerificationSuccess.defaultFile}`)); }); diff --git a/spec/Parse.Push.spec.js b/spec/Parse.Push.spec.js index 1732e426e3..143922852d 100644 --- a/spec/Parse.Push.spec.js +++ b/spec/Parse.Push.spec.js @@ -2,14 +2,12 @@ const request = require('../lib/request'); -const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - const pushCompleted = async pushId => { const query = new Parse.Query('_PushStatus'); query.equalTo('objectId', pushId); let result = await query.first({ useMasterKey: true }); while (!(result && result.get('status') === 'succeeded')) { - await sleep(100); + await jasmine.timeout(); result = await query.first({ useMasterKey: true }); } }; diff --git a/spec/ParseAPI.spec.js b/spec/ParseAPI.spec.js index 9b1a97af87..4f8190a4a6 100644 --- a/spec/ParseAPI.spec.js +++ b/spec/ParseAPI.spec.js @@ -1267,6 +1267,25 @@ describe('miscellaneous', function () { }); }); + it('test cloud function query parameters with array of pointers', async () => { + Parse.Cloud.define('echoParams', req => { + return req.params; + }); + const headers = { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-Javascript-Key': 'test', + }; + const response = await request({ + method: 'POST', + headers: headers, + url: 'http://localhost:8378/1/functions/echoParams', + body: '{"arr": [{ "__type": "Pointer", "className": "PointerTest" }]}', + }); + const res = response.data.result; + expect(res.arr.length).toEqual(1); + }); + it('can handle null params in cloud functions (regression test for #1742)', done => { Parse.Cloud.define('func', request => { expect(request.params.nullParam).toEqual(null); diff --git a/spec/ParseFile.spec.js b/spec/ParseFile.spec.js index ed21304d39..c7c58f8ad5 100644 --- a/spec/ParseFile.spec.js +++ b/spec/ParseFile.spec.js @@ -37,8 +37,14 @@ describe('Parse.File testing', () => { }); }); - it('works with _ContentType', done => { - request({ + it('works with _ContentType', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['*'], + }, + }); + let response = await request({ method: 'POST', url: 'http://localhost:8378/1/files/file', body: JSON.stringify({ @@ -47,21 +53,18 @@ describe('Parse.File testing', () => { _ContentType: 'text/html', base64: 'PGh0bWw+PC9odG1sPgo=', }), - }).then(response => { - const b = response.data; - expect(b.name).toMatch(/_file.html/); - expect(b.url).toMatch(/^http:\/\/localhost:8378\/1\/files\/test\/.*file.html$/); - request({ url: b.url }).then(response => { - const body = response.text; - try { - expect(response.headers['content-type']).toMatch('^text/html'); - expect(body).toEqual('\n'); - } catch (e) { - jfail(e); - } - done(); - }); }); + const b = response.data; + expect(b.name).toMatch(/_file.html/); + expect(b.url).toMatch(/^http:\/\/localhost:8378\/1\/files\/test\/.*file.html$/); + response = await request({ url: b.url }); + const body = response.text; + try { + expect(response.headers['content-type']).toMatch('^text/html'); + expect(body).toEqual('\n'); + } catch (e) { + jfail(e); + } }); it('works without Content-Type', done => { @@ -351,25 +354,28 @@ describe('Parse.File testing', () => { ok(object.toJSON().file.url); }); - it('content-type used with no extension', done => { + it('content-type used with no extension', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['*'], + }, + }); const headers = { 'Content-Type': 'text/html', 'X-Parse-Application-Id': 'test', 'X-Parse-REST-API-Key': 'rest', }; - request({ + let response = await request({ method: 'POST', headers: headers, url: 'http://localhost:8378/1/files/file', body: 'fee fi fo', - }).then(response => { - const b = response.data; - expect(b.name).toMatch(/\.html$/); - request({ url: b.url }).then(response => { - expect(response.headers['content-type']).toMatch(/^text\/html/); - done(); - }); }); + const b = response.data; + expect(b.name).toMatch(/\.html$/); + response = await request({ url: b.url }); + expect(response.headers['content-type']).toMatch(/^text\/html/); }); it('filename is url encoded', done => { @@ -1298,6 +1304,268 @@ describe('Parse.File testing', () => { await expectAsync(reconfigureServer({ fileUpload: { [key]: value } })).toBeResolved(); } } + await expectAsync( + reconfigureServer({ + fileUpload: { + fileExtensions: 1, + }, + }) + ).toBeRejectedWith('fileUpload.fileExtensions must be an array.'); + }); + }); + + describe('fileExtensions', () => { + it('works with _ContentType', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['png'], + }, + }); + await expectAsync( + request({ + method: 'POST', + url: 'http://localhost:8378/1/files/file', + body: JSON.stringify({ + _ApplicationId: 'test', + _JavaScriptKey: 'test', + _ContentType: 'text/html', + base64: 'PGh0bWw+PC9odG1sPgo=', + }), + }).catch(e => { + throw new Error(e.data.error); + }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `File upload of extension html is disabled.`) + ); + }); + + it('works without Content-Type', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + }, + }); + const headers = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + await expectAsync( + request({ + method: 'POST', + headers: headers, + url: 'http://localhost:8378/1/files/file.html', + body: '\n', + }).catch(e => { + throw new Error(e.data.error); + }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `File upload of extension html is disabled.`) + ); + }); + + it('default should allow common types', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + }, + }); + for (const type of ['plain', 'txt', 'png', 'jpg', 'gif', 'doc']) { + const file = new Parse.File(`parse-server-logo.${type}`, { base64: 'ParseA==' }); + await file.save(); + } + }); + + it('works with a period in the file name', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['^[^hH][^tT][^mM][^lL]?$'], + }, + }); + const headers = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + + const values = ['file.png.html', 'file.txt.png.html', 'file.png.txt.html']; + + for (const value of values) { + await expectAsync( + request({ + method: 'POST', + headers: headers, + url: `http://localhost:8378/1/files/${value}`, + body: '\n', + }).catch(e => { + throw new Error(e.data.error); + }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `File upload of extension html is disabled.`) + ); + } + }); + + it('works to stop invalid filenames', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['^[^hH][^tT][^mM][^lL]?$'], + }, + }); + const headers = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + + const values = [ + '!invalid.png', + '.png', + '.html', + ' .html', + '.png.html', + '~invalid.png', + '-invalid.png', + ]; + + for (const value of values) { + await expectAsync( + request({ + method: 'POST', + headers: headers, + url: `http://localhost:8378/1/files/${value}`, + body: '\n', + }).catch(e => { + throw new Error(e.data.error); + }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.INVALID_FILE_NAME, `Filename contains invalid characters.`) + ); + } + }); + + it('allows file without extension', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['^[^hH][^tT][^mM][^lL]?$'], + }, + }); + const headers = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + + const values = ['filenamewithoutextension']; + + for (const value of values) { + await expectAsync( + request({ + method: 'POST', + headers: headers, + url: `http://localhost:8378/1/files/${value}`, + body: '\n', + }).catch(e => { + throw new Error(e.data.error); + }) + ).toBeResolved(); + } + }); + + it('works with array', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['jpg', 'wav'], + }, + }); + await expectAsync( + request({ + method: 'POST', + url: 'http://localhost:8378/1/files/file', + body: JSON.stringify({ + _ApplicationId: 'test', + _JavaScriptKey: 'test', + _ContentType: 'text/html', + base64: 'PGh0bWw+PC9odG1sPgo=', + }), + }).catch(e => { + throw new Error(e.data.error); + }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `File upload of extension html is disabled.`) + ); + await expectAsync( + request({ + method: 'POST', + url: 'http://localhost:8378/1/files/file', + body: JSON.stringify({ + _ApplicationId: 'test', + _JavaScriptKey: 'test', + _ContentType: 'image/jpg', + base64: 'PGh0bWw+PC9odG1sPgo=', + }), + }) + ).toBeResolved(); + await expectAsync( + request({ + method: 'POST', + url: 'http://localhost:8378/1/files/file', + body: JSON.stringify({ + _ApplicationId: 'test', + _JavaScriptKey: 'test', + _ContentType: 'audio/wav', + base64: 'UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA', + }), + }) + ).toBeResolved(); + }); + + it('works with array without Content-Type', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['jpg'], + }, + }); + const headers = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }; + await expectAsync( + request({ + method: 'POST', + headers: headers, + url: 'http://localhost:8378/1/files/file.html', + body: '\n', + }).catch(e => { + throw new Error(e.data.error); + }) + ).toBeRejectedWith( + new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `File upload of extension html is disabled.`) + ); + }); + + it('works with array with correct file type', async () => { + await reconfigureServer({ + fileUpload: { + enableForPublic: true, + fileExtensions: ['html'], + }, + }); + const response = await request({ + method: 'POST', + url: 'http://localhost:8378/1/files/file', + body: JSON.stringify({ + _ApplicationId: 'test', + _JavaScriptKey: 'test', + _ContentType: 'text/html', + base64: 'PGh0bWw+PC9odG1sPgo=', + }), + }); + const b = response.data; + expect(b.name).toMatch(/_file.html$/); + expect(b.url).toMatch(/^http:\/\/localhost:8378\/1\/files\/test\/.*file.html$/); }); }); }); diff --git a/spec/ParseGeoPoint.spec.js b/spec/ParseGeoPoint.spec.js index 83868e8d8d..8454e60c74 100644 --- a/spec/ParseGeoPoint.spec.js +++ b/spec/ParseGeoPoint.spec.js @@ -47,7 +47,7 @@ describe('Parse.GeoPoint testing', () => { obj.set('location', point); obj.set('name', 'Zhoul'); await obj.save(); - Parse.Cloud.httpRequest({ + request({ url: 'http://localhost:8378/1/classes/TestObject/' + obj.id, headers: { 'X-Parse-Application-Id': 'test', diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index 205de6263c..45d21a2b9b 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -8,7 +8,7 @@ require('./helper'); const { updateCLP } = require('./support/dev'); const pluralize = require('pluralize'); -const { getMainDefinition } = require('apollo-utilities'); +const { getMainDefinition } = require('@apollo/client/utilities'); const { createUploadLink } = require('apollo-upload-client'); const { SubscriptionClient } = require('subscriptions-transport-ws'); const { WebSocketLink } = require('@apollo/client/link/ws'); @@ -49,7 +49,9 @@ describe('ParseGraphQLServer', () => { let parseGraphQLServer; beforeEach(async () => { - parseServer = await global.reconfigureServer({}); + parseServer = await global.reconfigureServer({ + maxUploadSize: '1kb', + }); parseGraphQLServer = new ParseGraphQLServer(parseServer, { graphQLPath: '/graphql', playgroundPath: '/playground', @@ -122,15 +124,16 @@ describe('ParseGraphQLServer', () => { info: new Object(), config: new Object(), auth: new Object(), + get: () => {}, + }; + const res = { + set: () => {}, }; it("should return schema and context with req's info, config and auth", async () => { const options = await parseGraphQLServer._getGraphQLOptions(); - expect(options.multipart).toEqual({ - fileSize: 20971520, - }); expect(options.schema).toEqual(parseGraphQLServer.parseGraphQLSchema.graphQLSchema); - const contextResponse = options.context({ req }); + const contextResponse = await options.context({ req, res }); expect(contextResponse.info).toEqual(req.info); expect(contextResponse.config).toEqual(req.config); expect(contextResponse.auth).toEqual(req.auth); @@ -292,30 +295,37 @@ describe('ParseGraphQLServer', () => { let objects = []; async function prepareData() { + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); user1 = new Parse.User(); user1.setUsername('user1'); user1.setPassword('user1'); user1.setEmail('user1@user1.user1'); + user1.setACL(acl); await user1.signUp(); user2 = new Parse.User(); user2.setUsername('user2'); user2.setPassword('user2'); + user2.setACL(acl); await user2.signUp(); user3 = new Parse.User(); user3.setUsername('user3'); user3.setPassword('user3'); + user3.setACL(acl); await user3.signUp(); user4 = new Parse.User(); user4.setUsername('user4'); user4.setPassword('user4'); + user4.setACL(acl); await user4.signUp(); user5 = new Parse.User(); user5.setUsername('user5'); user5.setPassword('user5'); + user5.setACL(acl); await user5.signUp(); const roleACL = new Parse.ACL(); @@ -425,7 +435,7 @@ describe('ParseGraphQLServer', () => { const expressApp = express(); httpServer = http.createServer(expressApp); expressApp.use('/parse', parseServer.app); - parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer, { + parseLiveQueryServer = await ParseServer.createLiveQueryServer(httpServer, { port: 1338, }); parseGraphQLServer.applyGraphQL(expressApp); @@ -942,8 +952,7 @@ describe('ParseGraphQLServer', () => { ).data['__type'].inputFields .map(field => field.name) .sort(); - - expect(inputFields).toEqual(['clientMutationId', 'password', 'username']); + expect(inputFields).toEqual(['authData', 'clientMutationId', 'password', 'username']); }); it('should have clientMutationId in log in mutation payload', async () => { @@ -5269,7 +5278,6 @@ describe('ParseGraphQLServer', () => { it('should only count', async () => { await prepareData(); - await parseGraphQLServer.parseGraphQLSchema.schemaCache.clear(); const where = { @@ -6827,7 +6835,7 @@ describe('ParseGraphQLServer', () => { describe('Files Mutations', () => { describe('Create', () => { - it_only_node_version('<17')('should return File object', async () => { + it('should return File object', async () => { const clientMutationId = uuidv4(); parseServer = await global.reconfigureServer({ @@ -7027,7 +7035,66 @@ describe('ParseGraphQLServer', () => { }); describe('Users Mutations', () => { + const challengeAdapter = { + validateAuthData: () => Promise.resolve({ response: { someData: true } }), + validateAppId: () => Promise.resolve(), + challenge: () => Promise.resolve({ someData: true }), + options: { anOption: true }, + }; + + it('should create user and return authData response', async () => { + parseServer = await global.reconfigureServer({ + publicServerURL: 'http://localhost:13377/parse', + auth: { + challengeAdapter, + }, + }); + const clientMutationId = uuidv4(); + + const result = await apolloClient.mutate({ + mutation: gql` + mutation createUser($input: CreateUserInput!) { + createUser(input: $input) { + clientMutationId + user { + id + authDataResponse + } + } + } + `, + variables: { + input: { + clientMutationId, + fields: { + authData: { + challengeAdapter: { + id: 'challengeAdapter', + }, + }, + }, + }, + }, + context: { + headers: { + 'X-Parse-Master-Key': 'test', + }, + }, + }); + + expect(result.data.createUser.clientMutationId).toEqual(clientMutationId); + expect(result.data.createUser.user.authDataResponse).toEqual({ + challengeAdapter: { someData: true }, + }); + }); + it('should sign user up', async () => { + parseServer = await global.reconfigureServer({ + publicServerURL: 'http://localhost:13377/parse', + auth: { + challengeAdapter, + }, + }); const clientMutationId = uuidv4(); const userSchema = new Parse.Schema('_User'); userSchema.addString('someField'); @@ -7044,6 +7111,7 @@ describe('ParseGraphQLServer', () => { sessionToken user { someField + authDataResponse aPointer { id username @@ -7059,11 +7127,17 @@ describe('ParseGraphQLServer', () => { fields: { username: 'user1', password: 'user1', + authData: { + challengeAdapter: { + id: 'challengeAdapter', + }, + }, aPointer: { createAndLink: { username: 'user2', password: 'user2', someField: 'someValue2', + ACL: { public: { read: true, write: true } }, }, }, someField: 'someValue', @@ -7078,6 +7152,9 @@ describe('ParseGraphQLServer', () => { expect(result.data.signUp.viewer.user.aPointer.id).toBeDefined(); expect(result.data.signUp.viewer.user.aPointer.username).toEqual('user2'); expect(typeof result.data.signUp.viewer.sessionToken).toBe('string'); + expect(result.data.signUp.viewer.user.authDataResponse).toEqual({ + challengeAdapter: { someData: true }, + }); }); it('should login with user', async () => { @@ -7086,6 +7163,7 @@ describe('ParseGraphQLServer', () => { parseServer = await global.reconfigureServer({ publicServerURL: 'http://localhost:13377/parse', auth: { + challengeAdapter, myAuth: { module: global.mockCustomAuthenticator('parse', 'graphql'), }, @@ -7105,6 +7183,7 @@ describe('ParseGraphQLServer', () => { sessionToken user { someField + authDataResponse aPointer { id username @@ -7118,6 +7197,7 @@ describe('ParseGraphQLServer', () => { input: { clientMutationId, authData: { + challengeAdapter: { id: 'challengeAdapter' }, myAuth: { id: 'parse', password: 'graphql', @@ -7130,6 +7210,7 @@ describe('ParseGraphQLServer', () => { username: 'user2', password: 'user2', someField: 'someValue2', + ACL: { public: { read: true, write: true } }, }, }, }, @@ -7143,9 +7224,92 @@ describe('ParseGraphQLServer', () => { expect(typeof result.data.logInWith.viewer.sessionToken).toBe('string'); expect(result.data.logInWith.viewer.user.aPointer.id).toBeDefined(); expect(result.data.logInWith.viewer.user.aPointer.username).toEqual('user2'); + expect(result.data.logInWith.viewer.user.authDataResponse).toEqual({ + challengeAdapter: { someData: true }, + }); + }); + + it('should handle challenge', async () => { + const clientMutationId = uuidv4(); + + spyOn(challengeAdapter, 'challenge').and.callThrough(); + parseServer = await global.reconfigureServer({ + publicServerURL: 'http://localhost:13377/parse', + auth: { + challengeAdapter, + }, + }); + + const user = new Parse.User(); + await user.save({ username: 'username', password: 'password' }); + + const result = await apolloClient.mutate({ + mutation: gql` + mutation Challenge($input: ChallengeInput!) { + challenge(input: $input) { + clientMutationId + challengeData + } + } + `, + variables: { + input: { + clientMutationId, + username: 'username', + password: 'password', + challengeData: { + challengeAdapter: { someChallengeData: true }, + }, + }, + }, + }); + + const challengeCall = challengeAdapter.challenge.calls.argsFor(0); + expect(challengeAdapter.challenge).toHaveBeenCalledTimes(1); + expect(challengeCall[0]).toEqual({ someChallengeData: true }); + expect(challengeCall[1]).toEqual(undefined); + expect(challengeCall[2]).toEqual(challengeAdapter); + expect(challengeCall[3].object instanceof Parse.User).toBeTruthy(); + expect(challengeCall[3].original instanceof Parse.User).toBeTruthy(); + expect(challengeCall[3].isChallenge).toBeTruthy(); + expect(challengeCall[3].object.id).toEqual(user.id); + expect(challengeCall[3].original.id).toEqual(user.id); + expect(result.data.challenge.clientMutationId).toEqual(clientMutationId); + expect(result.data.challenge.challengeData).toEqual({ + challengeAdapter: { someData: true }, + }); + + await expectAsync( + apolloClient.mutate({ + mutation: gql` + mutation Challenge($input: ChallengeInput!) { + challenge(input: $input) { + clientMutationId + challengeData + } + } + `, + variables: { + input: { + clientMutationId, + username: 'username', + password: 'wrongPassword', + challengeData: { + challengeAdapter: { someChallengeData: true }, + }, + }, + }, + }) + ).toBeRejected(); }); it('should log the user in', async () => { + parseServer = await global.reconfigureServer({ + publicServerURL: 'http://localhost:13377/parse', + auth: { + challengeAdapter, + }, + }); const clientMutationId = uuidv4(); const user = new Parse.User(); user.setUsername('user1'); @@ -7162,6 +7326,7 @@ describe('ParseGraphQLServer', () => { viewer { sessionToken user { + authDataResponse someField } } @@ -7173,6 +7338,7 @@ describe('ParseGraphQLServer', () => { clientMutationId, username: 'user1', password: 'user1', + authData: { challengeAdapter: { token: true } }, }, }, }); @@ -7181,6 +7347,9 @@ describe('ParseGraphQLServer', () => { expect(result.data.logIn.viewer.sessionToken).toBeDefined(); expect(result.data.logIn.viewer.user.someField).toEqual('someValue'); expect(typeof result.data.logIn.viewer.sessionToken).toBe('string'); + expect(result.data.logIn.viewer.user.authDataResponse).toEqual({ + challengeAdapter: { someData: true }, + }); }); it('should log the user out', async () => { @@ -8155,19 +8324,21 @@ describe('ParseGraphQLServer', () => { const someClass = new Parse.Object('SomeClass'); await someClass.save(); + const roleACL = new Parse.ACL(); + roleACL.setPublicReadAccess(true); + const user = new Parse.User(); user.set('username', 'username'); user.set('password', 'password'); + user.setACL(roleACL); await user.signUp(); const user2 = new Parse.User(); user2.set('username', 'username2'); user2.set('password', 'password2'); + user2.setACL(roleACL); await user2.signUp(); - const roleACL = new Parse.ACL(); - roleACL.setPublicReadAccess(true); - const role = new Parse.Role('aRole', roleACL); await role.save(); @@ -9130,7 +9301,7 @@ describe('ParseGraphQLServer', () => { expect(result6[0].node.name).toEqual('imACountry3'); }); - it_only_node_version('<17')('should support files', async () => { + it('should support files', async () => { try { parseServer = await global.reconfigureServer({ publicServerURL: 'http://localhost:13377/parse', @@ -9172,7 +9343,6 @@ describe('ParseGraphQLServer', () => { expect(res.status).toEqual(200); const result = JSON.parse(await res.text()); - expect(result.data.createFile.fileInfo.name).toEqual( jasmine.stringMatching(/_myFileName.txt$/) ); @@ -9378,9 +9548,169 @@ describe('ParseGraphQLServer', () => { } }); - it_only_node_version('<17')('should not upload if file is too large', async () => { - parseGraphQLServer.parseServer.config.maxUploadSize = '1kb'; + it('should support file upload for on fly creation through pointer and relation', async () => { + parseServer = await global.reconfigureServer({ + publicServerURL: 'http://localhost:13377/parse', + }); + const schema = new Parse.Schema('SomeClass'); + schema.addFile('someFileField'); + schema.addPointer('somePointerField', 'SomeClass'); + schema.addRelation('someRelationField', 'SomeClass'); + await schema.save(); + const body = new FormData(); + body.append( + 'operations', + JSON.stringify({ + query: ` + mutation UploadFiles( + $fields: CreateSomeClassFieldsInput + ) { + createSomeClass( + input: { fields: $fields } + ) { + someClass { + id + someFileField { + name + url + } + somePointerField { + id + someFileField { + name + url + } + } + someRelationField { + edges { + node { + id + someFileField { + name + url + } + } + } + } + } + } + } + `, + variables: { + fields: { + someFileField: { upload: null }, + somePointerField: { + createAndLink: { + someFileField: { upload: null }, + }, + }, + someRelationField: { + createAndAdd: [ + { + someFileField: { upload: null }, + }, + ], + }, + }, + }, + }) + ); + body.append( + 'map', + JSON.stringify({ + 1: ['variables.fields.someFileField.upload'], + 2: ['variables.fields.somePointerField.createAndLink.someFileField.upload'], + 3: ['variables.fields.someRelationField.createAndAdd.0.someFileField.upload'], + }) + ); + body.append('1', 'My File Content someFileField', { + filename: 'someFileField.txt', + contentType: 'text/plain', + }); + body.append('2', 'My File Content somePointerField', { + filename: 'somePointerField.txt', + contentType: 'text/plain', + }); + body.append('3', 'My File Content someRelationField', { + filename: 'someRelationField.txt', + contentType: 'text/plain', + }); + + const res = await fetch('http://localhost:13377/graphql', { + method: 'POST', + headers, + body, + }); + expect(res.status).toEqual(200); + const result = await res.json(); + console.log(result); + expect(result.data.createSomeClass.someClass.someFileField.name).toEqual( + jasmine.stringMatching(/_someFileField.txt$/) + ); + expect(result.data.createSomeClass.someClass.somePointerField.someFileField.name).toEqual( + jasmine.stringMatching(/_somePointerField.txt$/) + ); + expect( + result.data.createSomeClass.someClass.someRelationField.edges[0].node.someFileField.name + ).toEqual(jasmine.stringMatching(/_someRelationField.txt$/)); + }); + + it('should support files and add extension from mimetype', async () => { + try { + parseServer = await global.reconfigureServer({ + publicServerURL: 'http://localhost:13377/parse', + }); + + const body = new FormData(); + body.append( + 'operations', + JSON.stringify({ + query: ` + mutation CreateFile($input: CreateFileInput!) { + createFile(input: $input) { + fileInfo { + name + url + } + } + } + `, + variables: { + input: { + upload: null, + }, + }, + }) + ); + body.append('map', JSON.stringify({ 1: ['variables.input.upload'] })); + body.append('1', 'My File Content', { + // No extension, the system should add it from mimetype + filename: 'myFileName', + contentType: 'text/plain', + }); + + const res = await fetch('http://localhost:13377/graphql', { + method: 'POST', + headers, + body, + }); + + expect(res.status).toEqual(200); + + const result = JSON.parse(await res.text()); + expect(result.data.createFile.fileInfo.name).toEqual( + jasmine.stringMatching(/_myFileName.txt$/) + ); + expect(result.data.createFile.fileInfo.url).toEqual( + jasmine.stringMatching(/_myFileName.txt$/) + ); + } catch (e) { + handleError(e); + } + }); + + it('should not upload if file is too large', async () => { const body = new FormData(); body.append( 'operations', @@ -9405,6 +9735,7 @@ describe('ParseGraphQLServer', () => { body.append('map', JSON.stringify({ 1: ['variables.input.upload'] })); body.append( '1', + // In this test file parse server is setup with 1kb limit Buffer.alloc(parseGraphQLServer._transformMaxUploadSizeToBytes('2kb'), 1), { filename: 'myFileName.txt', @@ -9419,8 +9750,10 @@ describe('ParseGraphQLServer', () => { }); const result = JSON.parse(await res.text()); - expect(res.status).toEqual(500); - expect(result.errors[0].message).toEqual('File size limit exceeded: 1024 bytes'); + expect(res.status).toEqual(200); + expect(result.errors[0].message).toEqual( + 'File truncated as it exceeds the 1024 byte size limit.' + ); }); it('should support object values', async () => { @@ -10444,6 +10777,9 @@ describe('ParseGraphQLServer', () => { const user = new Parse.User(); user.setUsername('user1'); user.setPassword('user1'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); await user.signUp(); await parseGraphQLServer.parseGraphQLSchema.schemaCache.clear(); diff --git a/spec/ParseHooks.spec.js b/spec/ParseHooks.spec.js index d5d980d3d0..8d7c653fa2 100644 --- a/spec/ParseHooks.spec.js +++ b/spec/ParseHooks.spec.js @@ -190,7 +190,7 @@ describe('Hooks', () => { it('should fail trying to create two times the same function', done => { Parse.Hooks.createFunction('my_new_function', 'http://url.com') - .then(() => new Promise(resolve => setTimeout(resolve, 100))) + .then(() => jasmine.timeout()) .then( () => { return Parse.Hooks.createFunction('my_new_function', 'http://url.com'); @@ -208,7 +208,7 @@ describe('Hooks', () => { expect(err).not.toBe(null); if (err) { expect(err.code).toBe(143); - expect(err.message).toBe('function name: my_new_function already exits'); + expect(err.message).toBe('function name: my_new_function already exists'); } return Parse.Hooks.removeFunction('my_new_function'); } @@ -694,3 +694,36 @@ describe('triggers', () => { expect(req.context).toBeUndefined(); }); }); + +describe('sanitizing names', () => { + const invalidNames = [ + `test'%3bdeclare%20@q%20varchar(99)%3bset%20@q%3d'%5c%5cxxxxxxxxxxxxxxx.yyyyy'%2b'fy.com%5cxus'%3b%20exec%20master.dbo.xp_dirtree%20@q%3b--%20`, + `test.function.name`, + ]; + + it('should not crash server and return error on invalid Cloud Function name', async () => { + for (const invalidName of invalidNames) { + let error; + try { + await Parse.Cloud.run(invalidName); + } catch (err) { + error = err; + } + expect(error).toBeDefined(); + expect(error.message).toMatch(/Invalid function/); + } + }); + + it('should not crash server and return error on invalid Cloud Job name', async () => { + for (const invalidName of invalidNames) { + let error; + try { + await Parse.Cloud.startJob(invalidName); + } catch (err) { + error = err; + } + expect(error).toBeDefined(); + expect(error.message).toMatch(/Invalid job/); + } + }); +}); diff --git a/spec/ParseLiveQuery.spec.js b/spec/ParseLiveQuery.spec.js index d112fceded..015725ac46 100644 --- a/spec/ParseLiveQuery.spec.js +++ b/spec/ParseLiveQuery.spec.js @@ -1,11 +1,23 @@ 'use strict'; +const Auth = require('../lib/Auth'); const UserController = require('../lib/Controllers/UserController').UserController; const Config = require('../lib/Config'); +const ParseServer = require('../lib/index').ParseServer; +const triggers = require('../lib/triggers'); const validatorFail = () => { throw 'you are not authorized'; }; describe('ParseLiveQuery', function () { + beforeEach(() => { + Parse.CoreManager.getLiveQueryController().setDefaultLiveQueryClient(null); + }); + afterEach(async () => { + const client = await Parse.CoreManager.getLiveQueryController().getDefaultLiveQueryClient(); + client.close(); + // Wait for live query client to disconnect + await new Promise(resolve => setTimeout(resolve, 1000)); + }); it('access user on onLiveQueryEvent disconnect', async done => { await reconfigureServer({ liveQuery: { @@ -15,7 +27,6 @@ describe('ParseLiveQuery', function () { verbose: false, silent: true, }); - Parse.CoreManager.getLiveQueryController().setDefaultLiveQueryClient(null); const requestedUser = new Parse.User(); requestedUser.setUsername('username'); requestedUser.setPassword('password'); @@ -393,6 +404,49 @@ describe('ParseLiveQuery', function () { await object.save(); }); + xit('can handle live query with fields - enable upon JS SDK support', async () => { + await reconfigureServer({ + liveQuery: { + classNames: ['Test'], + }, + startLiveQueryServer: true, + }); + const query = new Parse.Query('Test'); + query.watch('yolo'); + const subscription = await query.subscribe(); + const spy = { + create(obj) { + if (!obj.get('yolo')) { + fail('create should not have been called'); + } + }, + update(object, original) { + if (object.get('yolo') === original.get('yolo')) { + fail('create should not have been called'); + } + }, + }; + const createSpy = spyOn(spy, 'create').and.callThrough(); + const updateSpy = spyOn(spy, 'update').and.callThrough(); + subscription.on('create', spy.create); + subscription.on('update', spy.update); + const obj = new Parse.Object('Test'); + obj.set('foo', 'bar'); + await obj.save(); + obj.set('foo', 'xyz'); + obj.set('yolo', 'xyz'); + await obj.save(); + const obj2 = new Parse.Object('Test'); + obj2.set('foo', 'bar'); + obj2.set('yolo', 'bar'); + await obj2.save(); + obj2.set('foo', 'bart'); + await obj2.save(); + await new Promise(resolve => setTimeout(resolve, 2000)); + expect(createSpy).toHaveBeenCalledTimes(1); + expect(updateSpy).toHaveBeenCalledTimes(1); + }); + it('can handle afterEvent set pointers', async done => { await reconfigureServer({ liveQuery: { @@ -469,76 +523,67 @@ describe('ParseLiveQuery', function () { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); const object = new TestObject(); await object.save(); - - Parse.Cloud.beforeSubscribe('TestObject', req => { - expect(req.op).toBe('subscribe'); - expect(req.requestId).toBe(1); - expect(req.query).toBeDefined(); - expect(req.user).toBeUndefined(); - }); - - Parse.Cloud.beforeConnect(req => { - expect(req.event).toBe('connect'); - expect(req.clients).toBe(0); - expect(req.subscriptions).toBe(0); - expect(req.useMasterKey).toBe(false); - expect(req.installationId).toBeDefined(); - expect(req.user).toBeUndefined(); - expect(req.client).toBeDefined(); - }); + const hooks = { + beforeSubscribe(req) { + expect(req.op).toBe('subscribe'); + expect(req.requestId).toBe(1); + expect(req.query).toBeDefined(); + expect(req.user).toBeUndefined(); + }, + beforeConnect(req) { + expect(req.event).toBe('connect'); + expect(req.clients).toBe(0); + expect(req.subscriptions).toBe(0); + expect(req.useMasterKey).toBe(false); + expect(req.installationId).toBeDefined(); + expect(req.user).toBeUndefined(); + expect(req.client).toBeDefined(); + }, + }; + spyOn(hooks, 'beforeSubscribe').and.callThrough(); + spyOn(hooks, 'beforeConnect').and.callThrough(); + Parse.Cloud.beforeSubscribe('TestObject', hooks.beforeSubscribe); + Parse.Cloud.beforeConnect(hooks.beforeConnect); const query = new Parse.Query(TestObject); query.equalTo('objectId', object.id); const subscription = await query.subscribe(); subscription.on('update', object => { expect(object.get('foo')).toBe('bar'); + expect(hooks.beforeConnect).toHaveBeenCalled(); + expect(hooks.beforeSubscribe).toHaveBeenCalled(); done(); }); object.set({ foo: 'bar' }); await object.save(); }); - it('can handle beforeConnect validation function', async done => { + it('can handle beforeConnect validation function', async () => { await reconfigureServer({ liveQuery: { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); const object = new TestObject(); await object.save(); - Parse.Cloud.beforeConnect(() => {}, validatorFail); - let complete = false; - Parse.LiveQuery.on('error', error => { - Parse.LiveQuery.removeAllListeners('error'); - if (complete) { - return; - } - complete = true; - expect(error).toBe('you are not authorized'); - done(); - }); const query = new Parse.Query(TestObject); query.equalTo('objectId', object.id); - await query.subscribe(); + await expectAsync(query.subscribe()).toBeRejectedWith( + new Parse.Error(Parse.Error.VALIDATION_ERROR, 'you are not authorized') + ); }); - it('can handle beforeSubscribe validation function', async done => { + it('can handle beforeSubscribe validation function', async () => { await reconfigureServer({ liveQuery: { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); const object = new TestObject(); await object.save(); @@ -546,11 +591,9 @@ describe('ParseLiveQuery', function () { Parse.Cloud.beforeSubscribe(TestObject, () => {}, validatorFail); const query = new Parse.Query(TestObject); query.equalTo('objectId', object.id); - const subscription = await query.subscribe(); - subscription.on('error', error => { - expect(error).toBe('you are not authorized'); - done(); - }); + await expectAsync(query.subscribe()).toBeRejectedWith( + new Parse.Error(Parse.Error.VALIDATION_ERROR, 'you are not authorized') + ); }); it('can handle afterEvent validation function', async done => { @@ -576,14 +619,12 @@ describe('ParseLiveQuery', function () { await object.save(); }); - it('can handle beforeConnect error', async done => { + it('can handle beforeConnect error', async () => { await reconfigureServer({ liveQuery: { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); const object = new TestObject(); await object.save(); @@ -591,14 +632,9 @@ describe('ParseLiveQuery', function () { Parse.Cloud.beforeConnect(() => { throw new Error('You shall not pass!'); }); - Parse.LiveQuery.on('error', error => { - Parse.LiveQuery.removeAllListeners('error'); - expect(error).toBe('You shall not pass!'); - done(); - }); const query = new Parse.Query(TestObject); query.equalTo('objectId', object.id); - await query.subscribe(); + await expectAsync(query.subscribe()).toBeRejectedWith(new Error('You shall not pass!')); }); it('can log on beforeConnect throw', async () => { @@ -607,8 +643,6 @@ describe('ParseLiveQuery', function () { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); const logger = require('../lib/logger').logger; @@ -620,22 +654,20 @@ describe('ParseLiveQuery', function () { foo.bar(); /* eslint-enable no-undef */ }); - new Parse.Query(TestObject).subscribe(); - await new Promise(resolve => Parse.LiveQuery.on('error', resolve)); - Parse.LiveQuery.removeAllListeners('error'); + await expectAsync(new Parse.Query(TestObject).subscribe()).toBeRejectedWith( + new Error('foo is not defined') + ); expect(logger.error).toHaveBeenCalledWith( `Failed running beforeConnect for session ${token} with:\n Error: {"message":"foo is not defined","code":141}` ); }); - it('can handle beforeSubscribe error', async done => { + it('can handle beforeSubscribe error', async () => { await reconfigureServer({ liveQuery: { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); const object = new TestObject(); await object.save(); @@ -643,17 +675,9 @@ describe('ParseLiveQuery', function () { Parse.Cloud.beforeSubscribe(TestObject, () => { throw new Error('You shall not subscribe!'); }); - Parse.LiveQuery.on('error', error => { - expect(error).toBe('You shall not subscribe!'); - }); const query = new Parse.Query(TestObject); query.equalTo('objectId', object.id); - const subscription = await query.subscribe(); - subscription.on('error', error => { - Parse.LiveQuery.removeAllListeners('error'); - expect(error).toBe('You shall not subscribe!'); - done(); - }); + await expectAsync(query.subscribe()).toBeRejectedWith(new Error('You shall not subscribe!')); }); it('can log on beforeSubscribe error', async () => { @@ -662,8 +686,6 @@ describe('ParseLiveQuery', function () { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); const logger = require('../lib/logger').logger; @@ -676,8 +698,7 @@ describe('ParseLiveQuery', function () { }); const query = new Parse.Query(TestObject); - const subscription = await query.subscribe(); - await new Promise(resolve => subscription.on('error', resolve)); + await expectAsync(query.subscribe()).toBeRejectedWith(new Error('foo is not defined')); expect(logger.error).toHaveBeenCalledWith( `Failed running beforeSubscribe on TestObject for session undefined with:\n Error: {"message":"foo is not defined","code":141}` @@ -690,29 +711,35 @@ describe('ParseLiveQuery', function () { classNames: ['TestObject'], }, startLiveQueryServer: true, - verbose: false, - silent: true, }); - Parse.Cloud.beforeSubscribe(TestObject, request => { - const query = request.query; - query.equalTo('yolo', 'abc'); - }); - + const hook = { + beforeSubscribe(request) { + request.query.equalTo('yolo', 'abc'); + }, + }; + spyOn(hook, 'beforeSubscribe').and.callThrough(); + Parse.Cloud.beforeSubscribe('TestObject', hook.beforeSubscribe); const object = new TestObject(); await object.save(); - const query = new Parse.Query(TestObject); + const query = new Parse.Query('TestObject'); query.equalTo('objectId', object.id); const subscription = await query.subscribe(); - subscription.on('update', () => { - fail(); + fail('beforeSubscribe should restrict subscription'); }); - object.set({ foo: 'bar' }); + subscription.on('enter', object => { + if (object.get('yolo') === 'abc') { + done(); + } else { + fail('beforeSubscribe should restrict queries'); + } + }); + object.set({ yolo: 'bar' }); await object.save(); - setTimeout(async () => { - done(); - }, 1000); + object.set({ yolo: 'abc' }); + await object.save(); + expect(hook.beforeSubscribe).toHaveBeenCalled(); }); it('can return a new beforeSubscribe query', async done => { @@ -910,26 +937,15 @@ describe('ParseLiveQuery', function () { await Parse.User.logIn('username', 'password'); }); - it('prevent liveQuery on Session class when not logged in', async done => { + it('prevent liveQuery on Session class when not logged in', async () => { await reconfigureServer({ liveQuery: { classNames: [Parse.Session], }, startLiveQueryServer: true, - verbose: false, - silent: true, - }); - - Parse.LiveQuery.on('error', error => { - expect(error).toBe('Invalid session token'); }); const query = new Parse.Query(Parse.Session); - const subscription = await query.subscribe(); - subscription.on('error', error => { - Parse.LiveQuery.removeAllListeners('error'); - expect(error).toBe('Invalid session token'); - done(); - }); + await expectAsync(query.subscribe()).toBeRejectedWith(new Error('Invalid session token')); }); it('handle invalid websocket payload length', async done => { @@ -977,6 +993,7 @@ describe('ParseLiveQuery', function () { }; await reconfigureServer({ + maintenanceKey: 'test2', liveQuery: { classNames: [Parse.User], }, @@ -998,9 +1015,14 @@ describe('ParseLiveQuery', function () { .signUp() .then(() => { const config = Config.get('test'); - return config.database.find('_User', { - username: 'zxcv', - }); + return config.database.find( + '_User', + { + username: 'zxcv', + }, + {}, + Auth.maintenance(config) + ); }) .then(async results => { const foundUser = results[0]; @@ -1076,6 +1098,9 @@ describe('ParseLiveQuery', function () { user.setUsername('username'); user.setPassword('password'); user.set('foo', 'bar'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); const query = new Parse.Query(Parse.User); query.equalTo('foo', 'bar'); @@ -1190,12 +1215,58 @@ describe('ParseLiveQuery', function () { await object.save(); }); - afterEach(async function (done) { + it('does shutdown liveQuery server', async () => { + await reconfigureServer({ appId: 'test_app_id' }); + const config = { + appId: 'hello_test', + masterKey: 'world', + port: 1345, + mountPath: '/1', + serverURL: 'http://localhost:1345/1', + liveQuery: { + classNames: ['Yolo'], + }, + startLiveQueryServer: true, + }; + if (process.env.PARSE_SERVER_TEST_DB === 'postgres') { + config.databaseAdapter = new databaseAdapter.constructor({ + uri: databaseURI, + collectionPrefix: 'test_', + }); + config.filesAdapter = defaultConfiguration.filesAdapter; + } + const server = await ParseServer.startApp(config); const client = await Parse.CoreManager.getLiveQueryController().getDefaultLiveQueryClient(); - client.close(); - // Wait for live query client to disconnect - setTimeout(() => { - done(); - }, 1000); + client.serverURL = 'ws://localhost:1345/1'; + const query = await new Parse.Query('Yolo').subscribe(); + await Promise.all([ + server.handleShutdown(), + new Promise(resolve => query.on('close', resolve)), + ]); + await new Promise(resolve => setTimeout(resolve, 100)); + expect(server.liveQueryServer.server.address()).toBeNull(); + expect(server.liveQueryServer.subscriber.isOpen).toBeFalse(); + await new Promise(resolve => server.server.close(resolve)); + }); + + it('prevent afterSave trigger if not exists', async () => { + await reconfigureServer({ + liveQuery: { + classNames: ['TestObject'], + }, + startLiveQueryServer: true, + verbose: false, + silent: true, + }); + spyOn(triggers, 'maybeRunTrigger').and.callThrough(); + const object1 = new TestObject(); + const object2 = new TestObject(); + const object3 = new TestObject(); + await Parse.Object.saveAll([object1, object2, object3]); + + expect(triggers.maybeRunTrigger).toHaveBeenCalledTimes(0); + expect(object1.id).toBeDefined(); + expect(object2.id).toBeDefined(); + expect(object3.id).toBeDefined(); }); }); diff --git a/spec/ParseLiveQueryRedis.spec.js b/spec/ParseLiveQueryRedis.spec.js new file mode 100644 index 0000000000..deb84bafb2 --- /dev/null +++ b/spec/ParseLiveQueryRedis.spec.js @@ -0,0 +1,58 @@ +if (process.env.PARSE_SERVER_TEST_CACHE === 'redis') { + describe('ParseLiveQuery redis', () => { + afterEach(async () => { + const client = await Parse.CoreManager.getLiveQueryController().getDefaultLiveQueryClient(); + client.close(); + }); + it('can connect', async () => { + await reconfigureServer({ + appId: 'redis_live_query', + startLiveQueryServer: true, + liveQuery: { + classNames: ['TestObject'], + redisURL: 'redis://localhost:6379', + }, + liveQueryServerOptions: { + redisURL: 'redis://localhost:6379', + }, + }); + const subscription = await new Parse.Query('TestObject').subscribe(); + const [object] = await Promise.all([ + new Parse.Object('TestObject').save(), + new Promise(resolve => + subscription.on('create', () => { + resolve(); + }) + ), + ]); + await Promise.all([ + new Promise(resolve => + subscription.on('delete', () => { + resolve(); + }) + ), + object.destroy(), + ]); + }); + + it('can call connect twice', async () => { + const server = await reconfigureServer({ + appId: 'redis_live_query', + startLiveQueryServer: true, + liveQuery: { + classNames: ['TestObject'], + redisURL: 'redis://localhost:6379', + }, + liveQueryServerOptions: { + redisURL: 'redis://localhost:6379', + }, + }); + expect(server.config.liveQueryController.liveQueryPublisher.parsePublisher.isOpen).toBeTrue(); + await server.config.liveQueryController.connect(); + expect(server.config.liveQueryController.liveQueryPublisher.parsePublisher.isOpen).toBeTrue(); + expect(server.liveQueryServer.subscriber.isOpen).toBe(true); + await server.liveQueryServer.connect(); + expect(server.liveQueryServer.subscriber.isOpen).toBe(true); + }); + }); +} diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 0d1a1e6387..04fb3fff58 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -94,29 +94,30 @@ describe('ParseLiveQueryServer', function () { expect(parseLiveQueryServer.subscriptions.size).toBe(0); }); - it('can be initialized from ParseServer', function () { + it('can be initialized from ParseServer', async () => { const httpServer = {}; - const parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer, {}); + const parseLiveQueryServer = await ParseServer.createLiveQueryServer(httpServer, {}); expect(parseLiveQueryServer.clientId).toBeUndefined(); expect(parseLiveQueryServer.clients.size).toBe(0); expect(parseLiveQueryServer.subscriptions.size).toBe(0); }); - it('can be initialized from ParseServer without httpServer', function (done) { - const parseLiveQueryServer = ParseServer.createLiveQueryServer(undefined, { + it('can be initialized from ParseServer without httpServer', async () => { + const parseLiveQueryServer = await ParseServer.createLiveQueryServer(undefined, { port: 22345, }); expect(parseLiveQueryServer.clientId).toBeUndefined(); expect(parseLiveQueryServer.clients.size).toBe(0); expect(parseLiveQueryServer.subscriptions.size).toBe(0); - parseLiveQueryServer.server.close(done); + await new Promise(resolve => parseLiveQueryServer.server.close(resolve)); }); describe_only_db('mongo')('initialization', () => { - it('can be initialized through ParseServer without liveQueryServerOptions', function (done) { - const parseServer = ParseServer.start({ + beforeEach(() => reconfigureServer({ appId: 'mongo_init_test' })); + it('can be initialized through ParseServer without liveQueryServerOptions', async () => { + const parseServer = await ParseServer.startApp({ appId: 'hello', masterKey: 'world', port: 22345, @@ -126,19 +127,14 @@ describe('ParseLiveQueryServer', function () { classNames: ['Yolo'], }, startLiveQueryServer: true, - serverStartComplete: () => { - expect(parseServer.liveQueryServer).not.toBeUndefined(); - expect(parseServer.liveQueryServer.server).toBe(parseServer.server); - parseServer.server.close(async () => { - await reconfigureServer(); - done(); - }); - }, }); + expect(parseServer.liveQueryServer).not.toBeUndefined(); + expect(parseServer.liveQueryServer.server).toBe(parseServer.server); + await new Promise(resolve => parseServer.server.close(resolve)); }); - it('can be initialized through ParseServer with liveQueryServerOptions', function (done) { - const parseServer = ParseServer.start({ + it('can be initialized through ParseServer with liveQueryServerOptions', async () => { + const parseServer = await ParseServer.startApp({ appId: 'hello', masterKey: 'world', port: 22346, @@ -150,17 +146,10 @@ describe('ParseLiveQueryServer', function () { liveQueryServerOptions: { port: 22347, }, - serverStartComplete: () => { - expect(parseServer.liveQueryServer).not.toBeUndefined(); - expect(parseServer.liveQueryServer.server).not.toBe(parseServer.server); - parseServer.liveQueryServer.server.close( - parseServer.server.close.bind(parseServer.server, async () => { - await reconfigureServer(); - done(); - }) - ); - }, }); + expect(parseServer.liveQueryServer).not.toBeUndefined(); + expect(parseServer.liveQueryServer.server).not.toBe(parseServer.server); + await new Promise(resolve => parseServer.server.close(resolve)); }); }); @@ -306,7 +295,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; const requestId = 2; const request = { @@ -343,7 +332,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; const requestId = 2; const request = { @@ -367,7 +356,7 @@ describe('ParseLiveQueryServer', function () { // Make sure we add subscriptionInfo to the client const args = client.addSubscriptionInfo.calls.first().args; expect(args[0]).toBe(requestId); - expect(args[1].fields).toBe(query.fields); + expect(args[1].keys).toBe(query.keys); expect(args[1].sessionToken).toBe(request.sessionToken); // Make sure we send subscribe response to the client expect(client.pushSubscribe).toHaveBeenCalledWith(requestId); @@ -390,7 +379,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; await addMockSubscription(parseLiveQueryServer, clientId, requestId, parseWebSocket, query); // Add subscription for mock client 2 @@ -402,7 +391,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['testAgain'], + keys: ['testAgain'], }; const requestIdAgain = 1; await addMockSubscription( @@ -428,7 +417,7 @@ describe('ParseLiveQueryServer', function () { // Make sure we add subscriptionInfo to the client 2 args = clientAgain.addSubscriptionInfo.calls.mostRecent().args; expect(args[0]).toBe(requestIdAgain); - expect(args[1].fields).toBe(queryAgain.fields); + expect(args[1].keys).toBe(queryAgain.keys); }); it('can handle unsubscribe command without clientId', function () { @@ -766,6 +755,49 @@ describe('ParseLiveQueryServer', function () { parseLiveQueryServer._onAfterSave(message); }); + it('sends correct object for dates', async () => { + jasmine.restoreLibrary('../lib/LiveQuery/QueryTools', 'matchesQuery'); + + const parseLiveQueryServer = new ParseLiveQueryServer({}); + + const date = new Date(); + const message = { + currentParseObject: { + date: { __type: 'Date', iso: date.toISOString() }, + __type: 'Object', + key: 'value', + className: testClassName, + }, + }; + // Add mock client + const clientId = 1; + const client = addMockClient(parseLiveQueryServer, clientId); + + const requestId2 = 2; + + await addMockSubscription(parseLiveQueryServer, clientId, requestId2); + + parseLiveQueryServer._matchesACL = function () { + return Promise.resolve(true); + }; + + parseLiveQueryServer._inflateParseObject(message); + parseLiveQueryServer._onAfterSave(message); + + // Make sure we send leave and enter command to client + await timeout(); + + expect(client.pushCreate).toHaveBeenCalledWith( + requestId2, + { + className: 'TestObject', + key: 'value', + date: { __type: 'Date', iso: date.toISOString() }, + }, + null + ); + }); + it('can handle object save command which does not match any subscription', async done => { const parseLiveQueryServer = new ParseLiveQueryServer({}); // Make mock request message @@ -1049,7 +1081,7 @@ describe('ParseLiveQueryServer', function () { done(); }); - it('can handle create command with fields', async done => { + it('can handle create command with keys', async done => { jasmine.restoreLibrary('../lib/LiveQuery/Client', 'Client'); const Client = require('../lib/LiveQuery/Client').Client; const parseLiveQueryServer = new ParseLiveQueryServer({}); @@ -1072,7 +1104,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; await addMockSubscription(parseLiveQueryServer, clientId, requestId, parseWebSocket, query); // Mock _matchesSubscription to return matching @@ -1099,6 +1131,61 @@ describe('ParseLiveQueryServer', function () { done(); }); + it('can handle create command with watch', async () => { + jasmine.restoreLibrary('../lib/LiveQuery/Client', 'Client'); + const Client = require('../lib/LiveQuery/Client').Client; + const parseLiveQueryServer = new ParseLiveQueryServer({}); + // Make mock request message + const message = generateMockMessage(); + + const clientId = 1; + const parseWebSocket = { + clientId, + send: jasmine.createSpy('send'), + }; + const client = new Client(clientId, parseWebSocket); + spyOn(client, 'pushCreate').and.callThrough(); + parseLiveQueryServer.clients.set(clientId, client); + + // Add mock subscription + const requestId = 2; + const query = { + className: testClassName, + where: { + key: 'value', + }, + watch: ['yolo'], + }; + await addMockSubscription(parseLiveQueryServer, clientId, requestId, parseWebSocket, query); + // Mock _matchesSubscription to return matching + parseLiveQueryServer._matchesSubscription = function (parseObject) { + if (!parseObject) { + return false; + } + return true; + }; + parseLiveQueryServer._matchesACL = function () { + return Promise.resolve(true); + }; + + parseLiveQueryServer._onAfterSave(message); + + // Make sure we send create command to client + await timeout(); + + expect(client.pushCreate).not.toHaveBeenCalled(); + + message.currentParseObject.set('yolo', 'test'); + parseLiveQueryServer._onAfterSave(message); + + await timeout(); + + const args = parseWebSocket.send.calls.mostRecent().args; + const toSend = JSON.parse(args[0]); + expect(toSend.object).toBeDefined(); + expect(toSend.original).toBeUndefined(); + }); + it('can match subscription for null or undefined parse object', function () { const parseLiveQueryServer = new ParseLiveQueryServer({}); // Make mock subscription @@ -1822,7 +1909,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; } const request = { @@ -1846,6 +1933,7 @@ describe('ParseLiveQueryServer', function () { } else { subscription.clientRequestIds = new Map([[clientId, [requestId]]]); } + subscription.query = query.where; return subscription; } diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index 5bfe22683f..a61305286c 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -23,28 +23,28 @@ const loadTestData = () => { const data1 = { score: 10, name: 'foo', - sender: { group: 'A' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'A' }, views: 900, size: ['S', 'M'], }; const data2 = { score: 10, name: 'foo', - sender: { group: 'A' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'A' }, views: 800, size: ['M', 'L'], }; const data3 = { score: 10, name: 'bar', - sender: { group: 'B' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'B' }, views: 700, size: ['S'], }; const data4 = { score: 20, name: 'dpl', - sender: { group: 'B' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'B' }, views: 700, size: ['S'], }; @@ -86,7 +86,7 @@ describe('Parse.Query Aggregate testing', () => { it('invalid query group _id required', done => { const options = Object.assign({}, masterKeyOptions, { body: { - group: {}, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: {}, }, }); get(Parse.serverURL + '/aggregate/TestObject', options).catch(error => { @@ -98,7 +98,7 @@ describe('Parse.Query Aggregate testing', () => { it('group by field', done => { const options = Object.assign({}, masterKeyOptions, { body: { - group: { objectId: '$name' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '$name' }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -119,7 +119,7 @@ describe('Parse.Query Aggregate testing', () => { const options = Object.assign({}, masterKeyOptions, { body: { pipeline: { - group: { objectId: '$name' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '$name' }, }, }, }); @@ -137,7 +137,7 @@ describe('Parse.Query Aggregate testing', () => { const obj = new TestObject(); const pipeline = [ { - group: { objectId: {} }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: {} }, }, ]; obj @@ -156,7 +156,7 @@ describe('Parse.Query Aggregate testing', () => { const obj = new TestObject(); const pipeline = [ { - group: { objectId: '' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '' }, }, ]; obj @@ -175,7 +175,7 @@ describe('Parse.Query Aggregate testing', () => { const obj = new TestObject(); const pipeline = [ { - group: { objectId: [] }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: [] }, }, ]; obj @@ -196,9 +196,8 @@ describe('Parse.Query Aggregate testing', () => { const obj3 = new TestObject(); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: { + $group: { + _id: { score: '$score', views: '$views', }, @@ -280,7 +279,7 @@ describe('Parse.Query Aggregate testing', () => { it('group by number', done => { const options = Object.assign({}, masterKeyOptions, { body: { - group: { objectId: '$score' }, // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '$score' }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -302,9 +301,8 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 }); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: null, + $group: { + _id: null, total: { $sum: { $multiply: ['$quantity', '$price'] } }, }, }, @@ -326,10 +324,10 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 }); const pipeline = [ { - match: { quantity: { $exists: true } }, + $match: { quantity: { $exists: true } }, }, { - project: { + $project: { name: 1, total: { $multiply: ['$quantity', '$price'] }, }, @@ -358,16 +356,16 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 }); const pipeline = [ { - match: { quantity: { $exists: true } }, + $match: { quantity: { $exists: true } }, }, { - project: { - objectId: 0, // TODO: change to `_id`. See [#7339](https://bit.ly/3incnWx) + $project: { + _id: 0, total: { $multiply: ['$quantity', '$price'] }, }, }, { - sort: { total: 1 }, + $sort: { total: 1 }, }, ]; Parse.Object.saveAll([obj1, obj2]) @@ -388,7 +386,7 @@ describe('Parse.Query Aggregate testing', () => { it_exclude_dbs(['postgres'])('project updatedAt only transform', done => { const pipeline = [ { - project: { objectId: 0, updatedAt: 1 }, + $project: { _id: 0, updatedAt: 1 }, }, ]; const query = new Parse.Query(TestObject); @@ -411,13 +409,13 @@ describe('Parse.Query Aggregate testing', () => { const obj3 = new TestObject({ dateField2019: new Date(1990, 11, 1) }); const pipeline = [ { - match: { + $match: { dateField2019: { $exists: true }, }, }, { - group: { - objectId: { + $group: { + _id: { day: { $dayOfMonth: '$dateField2019' }, month: { $month: '$dateField2019' }, year: { $year: '$dateField2019' }, @@ -449,9 +447,8 @@ describe('Parse.Query Aggregate testing', () => { const obj3 = new TestObject({ dateField2019: new Date(1990, 11, 1) }); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: { + $group: { + _id: { day: { $dayOfMonth: '$dateField2019' }, month: { $month: '$dateField2019' }, year: { $year: '$dateField2019' }, @@ -481,7 +478,7 @@ describe('Parse.Query Aggregate testing', () => { const obj1 = new TestObject({ pointer: pointer1 }); const obj2 = new TestObject({ pointer: pointer2 }); const obj3 = new TestObject({ pointer: pointer1 }); - const pipeline = [{ group: { objectId: '$pointer' } }]; + const pipeline = [{ $group: { _id: '$pointer' } }]; Parse.Object.saveAll([pointer1, pointer2, obj1, obj2, obj3]) .then(() => { const query = new Parse.Query(TestObject); @@ -499,8 +496,7 @@ describe('Parse.Query Aggregate testing', () => { it('group sum query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: '$score' } }, + $group: { _id: null, total: { $sum: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -516,8 +512,7 @@ describe('Parse.Query Aggregate testing', () => { it('group count query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: 1 } }, + $group: { _id: null, total: { $sum: 1 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -533,8 +528,7 @@ describe('Parse.Query Aggregate testing', () => { it('group min query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, minScore: { $min: '$score' } }, + $group: { _id: null, minScore: { $min: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -550,8 +544,7 @@ describe('Parse.Query Aggregate testing', () => { it('group max query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, maxScore: { $max: '$score' } }, + $group: { _id: null, maxScore: { $max: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -567,8 +560,7 @@ describe('Parse.Query Aggregate testing', () => { it('group avg query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, avgScore: { $avg: '$score' } }, + $group: { _id: null, avgScore: { $avg: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -584,7 +576,7 @@ describe('Parse.Query Aggregate testing', () => { it('limit query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - limit: 2, + $limit: 2, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -598,7 +590,7 @@ describe('Parse.Query Aggregate testing', () => { it('sort ascending query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - sort: { name: 1 }, + $sort: { name: 1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -616,7 +608,7 @@ describe('Parse.Query Aggregate testing', () => { it('sort decending query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - sort: { name: -1 }, + $sort: { name: -1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -634,7 +626,7 @@ describe('Parse.Query Aggregate testing', () => { it('skip query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - skip: 2, + $skip: 2, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -654,7 +646,7 @@ describe('Parse.Query Aggregate testing', () => { const obj1 = new TestObject({ dateField: yesterday }); const obj2 = new TestObject({ dateField: today }); const obj3 = new TestObject({ dateField: tomorrow }); - const pipeline = [{ match: { dateField: { $lt: tomorrow } } }]; + const pipeline = [{ $match: { dateField: { $lt: tomorrow } } }]; Parse.Object.saveAll([obj1, obj2, obj3]) .then(() => { const query = new Parse.Query(TestObject); @@ -686,7 +678,7 @@ describe('Parse.Query Aggregate testing', () => { it('match comparison query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 15 } }, + $match: { score: { $gt: 15 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -701,7 +693,7 @@ describe('Parse.Query Aggregate testing', () => { it('match multiple comparison query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 5, $lt: 15 } }, + $match: { score: { $gt: 5, $lt: 15 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -718,7 +710,7 @@ describe('Parse.Query Aggregate testing', () => { it('match complex comparison query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 5, $lt: 15 }, views: { $gt: 850, $lt: 1000 } }, + $match: { score: { $gt: 5, $lt: 15 }, views: { $gt: 850, $lt: 1000 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -734,7 +726,7 @@ describe('Parse.Query Aggregate testing', () => { it('match comparison and equality query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 5, $lt: 15 }, views: 900 }, + $match: { score: { $gt: 5, $lt: 15 }, views: 900 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -750,7 +742,7 @@ describe('Parse.Query Aggregate testing', () => { it('match $or query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { + $match: { $or: [{ score: { $gt: 15, $lt: 25 } }, { views: { $gt: 750, $lt: 850 } }], }, }, @@ -775,7 +767,7 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject(); Parse.Object.saveAll([obj1, obj2]) .then(() => { - const pipeline = [{ match: { objectId: obj1.id } }]; + const pipeline = [{ $match: { _id: obj1.id } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -791,7 +783,7 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'TestObject2' }); Parse.Object.saveAll([obj1, obj2]) .then(() => { - const pipeline = [{ match: { name: 'TestObject1' } }]; + const pipeline = [{ $match: { name: 'TestObject1' } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -811,7 +803,7 @@ describe('Parse.Query Aggregate testing', () => { Parse.Object.saveAll([pointer1, pointer2, obj1, obj2, obj3]) .then(() => { - const pipeline = [{ match: { pointer: pointer1.id } }]; + const pipeline = [{ $match: { pointer: pointer1.id } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -826,7 +818,7 @@ describe('Parse.Query Aggregate testing', () => { }); it_exclude_dbs(['postgres'])('match exists query', done => { - const pipeline = [{ match: { score: { $exists: true } } }]; + const pipeline = [{ $match: { score: { $exists: true } } }]; const query = new Parse.Query(TestObject); query.aggregate(pipeline).then(results => { expect(results.length).toEqual(4); @@ -842,7 +834,7 @@ describe('Parse.Query Aggregate testing', () => { .then(() => { const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); - const pipeline = [{ match: { createdAt: { $gte: today } } }]; + const pipeline = [{ $match: { createdAt: { $gte: today } } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -861,7 +853,7 @@ describe('Parse.Query Aggregate testing', () => { .then(() => { const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); - const pipeline = [{ match: { updatedAt: { $gte: today } } }]; + const pipeline = [{ $match: { updatedAt: { $gte: today } } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -880,7 +872,7 @@ describe('Parse.Query Aggregate testing', () => { .then(() => { const now = new Date(); const future = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate()); - const pipeline = [{ match: { createdAt: future } }]; + const pipeline = [{ $match: { createdAt: future } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -899,7 +891,7 @@ describe('Parse.Query Aggregate testing', () => { Parse.Object.saveAll([pointer, obj1, obj2, obj3]) .then(() => { - const pipeline = [{ match: { pointer: { $exists: true } } }]; + const pipeline = [{ $match: { pointer: { $exists: true } } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -938,7 +930,7 @@ describe('Parse.Query Aggregate testing', () => { ( await new Parse.Query('MyCollection').aggregate([ { - match: { + $match: { language: { $in: [null, 'en'] }, }, }, @@ -952,7 +944,7 @@ describe('Parse.Query Aggregate testing', () => { ( await new Parse.Query('MyCollection').aggregate([ { - match: { + $match: { $or: [{ language: 'en' }, { language: null }], }, }, @@ -966,7 +958,7 @@ describe('Parse.Query Aggregate testing', () => { it('project query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - project: { name: 1 }, + $project: { name: 1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -986,7 +978,7 @@ describe('Parse.Query Aggregate testing', () => { it('multiple project query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - project: { name: 1, score: 1, sender: 1 }, + $project: { name: 1, score: 1, sender: 1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -1011,8 +1003,8 @@ describe('Parse.Query Aggregate testing', () => { .save() .then(() => { const pipeline = [ - { match: { objectId: obj.id } }, - { project: { pointer: 1, name: 1, createdAt: 1 } }, + { $match: { _id: obj.id } }, + { $project: { pointer: 1, name: 1, createdAt: 1 } }, ]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); @@ -1029,9 +1021,8 @@ describe('Parse.Query Aggregate testing', () => { it('project with group query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - project: { score: 1 }, - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: '$score', score: { $sum: '$score' } }, + $project: { score: 1 }, + $group: { _id: '$score', score: { $sum: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -1058,8 +1049,7 @@ describe('Parse.Query Aggregate testing', () => { it('class does not exist return empty', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: '$score' } }, + $group: { _id: null, total: { $sum: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/UnknownClass', options) @@ -1073,8 +1063,7 @@ describe('Parse.Query Aggregate testing', () => { it('field does not exist return empty', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: '$unknownfield' } }, + $group: { _id: null, total: { $sum: '$unknownfield' } }, }, }); get(Parse.serverURL + '/aggregate/UnknownClass', options) @@ -1103,7 +1092,7 @@ describe('Parse.Query Aggregate testing', () => { const options = Object.assign({}, masterKeyOptions, { body: { distinct: 'score', - where: { + $where: { name: 'bar', }, }, @@ -1120,7 +1109,7 @@ describe('Parse.Query Aggregate testing', () => { const options = Object.assign({}, masterKeyOptions, { body: { distinct: 'score', - where: JSON.stringify({ name: 'bar' }), + $where: JSON.stringify({ name: 'bar' }), }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -1270,7 +1259,7 @@ describe('Parse.Query Aggregate testing', () => { it('does not return sensitive hidden properties', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { + $match: { score: { $gt: 5, }, @@ -1317,7 +1306,7 @@ describe('Parse.Query Aggregate testing', () => { }); it_exclude_dbs(['postgres'])('aggregate allow multiple of same stage', async done => { - await reconfigureServer(); + await reconfigureServer({ silent: false }); const pointer1 = new TestObject({ value: 1 }); const pointer2 = new TestObject({ value: 2 }); const pointer3 = new TestObject({ value: 3 }); @@ -1330,17 +1319,17 @@ describe('Parse.Query Aggregate testing', () => { body: { pipeline: [ { - match: { name: 'Hello' }, + $match: { name: 'Hello' }, }, { // Transform className$objectId to objectId and store in new field tempPointer - project: { + $project: { tempPointer: { $substr: ['$_p_pointer', 11, -1] }, // Remove TestObject$ }, }, { // Left Join, replace objectId stored in tempPointer with an actual object - lookup: { + $lookup: { from: 'test_TestObject', localField: 'tempPointer', foreignField: '_id', @@ -1349,12 +1338,12 @@ describe('Parse.Query Aggregate testing', () => { }, { // lookup returns an array, Deconstructs an array field to objects - unwind: { + $unwind: { path: '$tempPointer', }, }, { - match: { 'tempPointer.value': 2 }, + $match: { 'tempPointer.value': 2 }, }, ], }, @@ -1398,7 +1387,7 @@ describe('Parse.Query Aggregate testing', () => { // Create query const pipeline = [ { - geoNear: { + $geoNear: { near: { type: 'Point', coordinates: [1, 1], @@ -1451,7 +1440,7 @@ describe('Parse.Query Aggregate testing', () => { // Create query const pipeline = [ { - geoNear: { + $geoNear: { near: { type: 'Point', coordinates: [1, 1], @@ -1497,7 +1486,7 @@ describe('Parse.Query Aggregate testing', () => { // Create query const pipeline = [ { - geoNear: { + $geoNear: { near: [1, 1], key: 'location', spherical: true, diff --git a/spec/ParseQuery.Comment.spec.js b/spec/ParseQuery.Comment.spec.js new file mode 100644 index 0000000000..12713387a0 --- /dev/null +++ b/spec/ParseQuery.Comment.spec.js @@ -0,0 +1,109 @@ +'use strict'; + +const Config = require('../lib/Config'); +const { MongoClient } = require('mongodb'); +const databaseURI = 'mongodb://localhost:27017/'; +const request = require('../lib/request'); + +let config, client, database; + +const masterKeyHeaders = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Rest-API-Key': 'rest', + 'X-Parse-Master-Key': 'test', + 'Content-Type': 'application/json', +}; + +const masterKeyOptions = { + headers: masterKeyHeaders, + json: true, +}; + +const profileLevel = 2; +describe_only_db('mongo')('Parse.Query with comment testing', () => { + beforeAll(async () => { + config = Config.get('test'); + client = await MongoClient.connect(databaseURI, { + useNewUrlParser: true, + useUnifiedTopology: true, + }); + database = client.db('parseServerMongoAdapterTestDatabase'); + let profiler = await database.command({ profile: 0 }); + expect(profiler.was).toEqual(0); + console.log(`Disabling profiler : ${profiler.was}`); + profiler = await database.command({ profile: profileLevel }); + profiler = await database.command({ profile: -1 }); + console.log(`Enabling profiler : ${profiler.was}`); + profiler = await database.command({ profile: -1 }); + expect(profiler.was).toEqual(profileLevel); + }); + + beforeEach(async () => { + const profiler = await database.command({ profile: -1 }); + expect(profiler.was).toEqual(profileLevel); + }); + + afterAll(async () => { + await database.command({ profile: 0 }); + await client.close(); + }); + + it('send comment with query through REST', async () => { + const comment = 'Hello Parse'; + const object = new TestObject(); + object.set('name', 'object'); + await object.save(); + const options = Object.assign({}, masterKeyOptions, { + url: Parse.serverURL + '/classes/TestObject', + qs: { + explain: true, + comment: comment, + }, + }); + await request(options); + const result = await database.collection('system.profile').findOne({}, { sort: { ts: -1 } }); + expect(result.command.explain.comment).toBe(comment); + }); + + it('send comment with query', async () => { + const comment = 'Hello Parse'; + const object = new TestObject(); + object.set('name', 'object'); + await object.save(); + const collection = await config.database.adapter._adaptiveCollection('TestObject'); + await collection._rawFind({ name: 'object' }, { comment: comment }); + const result = await database.collection('system.profile').findOne({}, { sort: { ts: -1 } }); + expect(result.command.comment).toBe(comment); + }); + + it('send a comment with a count query', async () => { + const comment = 'Hello Parse'; + const object = new TestObject(); + object.set('name', 'object'); + await object.save(); + + const object2 = new TestObject(); + object2.set('name', 'object'); + await object2.save(); + + const collection = await config.database.adapter._adaptiveCollection('TestObject'); + const countResult = await collection.count({ name: 'object' }, { comment: comment }); + expect(countResult).toEqual(2); + const result = await database.collection('system.profile').findOne({}, { sort: { ts: -1 } }); + expect(result.command.comment).toBe(comment); + }); + + it('attach a comment to an aggregation', async () => { + const comment = 'Hello Parse'; + const object = new TestObject(); + object.set('name', 'object'); + await object.save(); + const collection = await config.database.adapter._adaptiveCollection('TestObject'); + await collection.aggregate([{ $group: { _id: '$name' } }], { + explain: true, + comment: comment, + }); + const result = await database.collection('system.profile').findOne({}, { sort: { ts: -1 } }); + expect(result.command.explain.comment).toBe(comment); + }); +}); diff --git a/spec/ParseQuery.hint.spec.js b/spec/ParseQuery.hint.spec.js index e5498bab96..7ebffa4d34 100644 --- a/spec/ParseQuery.hint.spec.js +++ b/spec/ParseQuery.hint.spec.js @@ -86,6 +86,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { let result = await collection.aggregate([{ $group: { _id: '$foo' } }], { explain: true, }); + let { queryPlanner } = result[0].stages[0].$cursor; expect(queryPlanner.winningPlan.stage).toBe('COLLSCAN'); @@ -93,6 +94,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { hint: '_id_', explain: true, }); + queryPlanner = result[0].stages[0].$cursor.queryPlanner; expect(queryPlanner.winningPlan.stage).toBe('FETCH'); expect(queryPlanner.winningPlan.inputStage.indexName).toBe('_id_'); @@ -322,7 +324,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -334,7 +336,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); @@ -349,7 +351,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -363,7 +365,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); @@ -382,7 +384,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -396,7 +398,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); @@ -415,7 +417,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -429,7 +431,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); diff --git a/spec/ParseRole.spec.js b/spec/ParseRole.spec.js index 47fed865fb..31de5b661e 100644 --- a/spec/ParseRole.spec.js +++ b/spec/ParseRole.spec.js @@ -142,7 +142,7 @@ describe('Parse Role testing', () => { return Promise.all(promises); }; - const restExecute = spyOn(RestQuery.prototype, 'execute').and.callThrough(); + const restExecute = spyOn(RestQuery._UnsafeRestQuery.prototype, 'execute').and.callThrough(); let user, auth, getAllRolesSpy; createTestUser() diff --git a/spec/ParseServer.spec.js b/spec/ParseServer.spec.js index fcb15f643f..b55c6fc548 100644 --- a/spec/ParseServer.spec.js +++ b/spec/ParseServer.spec.js @@ -29,27 +29,20 @@ describe('Server Url Checks', () => { server.close(done); }); - it('validate good server url', done => { + it('validate good server url', async () => { Parse.serverURL = 'http://localhost:13376'; - ParseServer.verifyServerUrl(async result => { - if (!result) { - done.fail('Did not pass valid url'); - } - await reconfigureServer(); - done(); - }); + const response = await ParseServer.verifyServerUrl(); + expect(response).toBeTrue(); }); - it('mark bad server url', done => { + it('mark bad server url', async () => { spyOn(console, 'warn').and.callFake(() => {}); Parse.serverURL = 'notavalidurl'; - ParseServer.verifyServerUrl(async result => { - if (result) { - done.fail('Did not mark invalid url'); - } - await reconfigureServer(); - done(); - }); + const response = await ParseServer.verifyServerUrl(); + expect(response).not.toBeTrue(); + expect(console.warn).toHaveBeenCalledWith( + `\nWARNING, Unable to connect to 'notavalidurl' as the URL is invalid. Cloud code and push notifications may be unavailable!\n` + ); }); xit('handleShutdown, close connection', done => { @@ -92,7 +85,7 @@ describe('Server Url Checks', () => { close = true; }, }); - const parseServer = ParseServer.start(newConfiguration); + const parseServer = ParseServer.startApp(newConfiguration); }); it('does not have unhandled promise rejection in the case of load error', done => { diff --git a/spec/ParseServerRESTController.spec.js b/spec/ParseServerRESTController.spec.js index 0ec52ed4b5..5e6a550e25 100644 --- a/spec/ParseServerRESTController.spec.js +++ b/spec/ParseServerRESTController.spec.js @@ -2,7 +2,6 @@ const ParseServerRESTController = require('../lib/ParseServerRESTController') .ParseServerRESTController; const ParseServer = require('../lib/ParseServer').default; const Parse = require('parse/node').Parse; -const semver = require('semver'); const TestUtils = require('../lib/TestUtils'); let RESTController; @@ -130,19 +129,13 @@ describe('ParseServerRESTController', () => { }); if ( - (semver.satisfies(process.env.MONGODB_VERSION, '>=4.0.4') && - process.env.MONGODB_TOPOLOGY === 'replicaset' && - process.env.MONGODB_STORAGE_ENGINE === 'wiredTiger') || + process.env.MONGODB_TOPOLOGY === 'replicaset' || process.env.PARSE_SERVER_TEST_DB === 'postgres' ) { describe('transactions', () => { beforeEach(async () => { await TestUtils.destroyAllDataPermanently(true); - if ( - semver.satisfies(process.env.MONGODB_VERSION, '>=4.0.4') && - process.env.MONGODB_TOPOLOGY === 'replicaset' && - process.env.MONGODB_STORAGE_ENGINE === 'wiredTiger' - ) { + if (process.env.MONGODB_TOPOLOGY === 'replicaset') { await reconfigureServer({ databaseAdapter: undefined, databaseURI: diff --git a/spec/ParseSession.spec.js b/spec/ParseSession.spec.js index a85be1a95e..aca4c07263 100644 --- a/spec/ParseSession.spec.js +++ b/spec/ParseSession.spec.js @@ -6,6 +6,8 @@ const request = require('../lib/request'); function setupTestUsers() { + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); const user1 = new Parse.User(); const user2 = new Parse.User(); const user3 = new Parse.User(); @@ -18,6 +20,10 @@ function setupTestUsers() { user2.set('password', 'password'); user3.set('password', 'password'); + user1.setACL(acl); + user2.setACL(acl); + user3.setACL(acl); + return user1 .signUp() .then(() => { diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 92301316e4..e97db08a6c 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -13,6 +13,30 @@ const passwordCrypto = require('../lib/password'); const Config = require('../lib/Config'); const cryptoUtils = require('../lib/cryptoUtils'); +describe('allowExpiredAuthDataToken option', () => { + it('should accept true value', async () => { + await reconfigureServer({ allowExpiredAuthDataToken: true }); + expect(Config.get(Parse.applicationId).allowExpiredAuthDataToken).toBe(true); + }); + + it('should accept false value', async () => { + await reconfigureServer({ allowExpiredAuthDataToken: false }); + expect(Config.get(Parse.applicationId).allowExpiredAuthDataToken).toBe(false); + }); + + it('should default false', async () => { + await reconfigureServer({}); + expect(Config.get(Parse.applicationId).allowExpiredAuthDataToken).toBe(false); + }); + + it('should enforce boolean values', async () => { + const options = [[], 'a', '', 0, 1, {}, 'true', 'false']; + for (const option of options) { + await expectAsync(reconfigureServer({ allowExpiredAuthDataToken: option })).toBeRejected(); + } + }); +}); + describe('Parse.User testing', () => { it('user sign up class method', async done => { const user = await Parse.User.signUp('asdf', 'zxcv'); @@ -50,6 +74,36 @@ describe('Parse.User testing', () => { } }); + it('user login with context', async () => { + let hit = 0; + const context = { foo: 'bar' }; + Parse.Cloud.beforeLogin(req => { + expect(req.context).toEqual(context); + hit++; + }); + Parse.Cloud.afterLogin(req => { + expect(req.context).toEqual(context); + hit++; + }); + await Parse.User.signUp('asdf', 'zxcv'); + await request({ + method: 'POST', + url: 'http://localhost:8378/1/login', + headers: { + 'X-Parse-Application-Id': Parse.applicationId, + 'X-Parse-REST-API-Key': 'rest', + 'X-Parse-Cloud-Context': JSON.stringify(context), + 'Content-Type': 'application/json', + }, + body: { + _method: 'GET', + username: 'asdf', + password: 'zxcv', + }, + }); + expect(hit).toBe(2); + }); + it('user login with non-string username with REST API', async done => { await Parse.User.signUp('asdf', 'zxcv'); request({ @@ -139,14 +193,13 @@ describe('Parse.User testing', () => { const ACL = user.getACL(); expect(ACL.getReadAccess(user)).toBe(true); expect(ACL.getWriteAccess(user)).toBe(true); - expect(ACL.getPublicReadAccess()).toBe(true); + expect(ACL.getPublicReadAccess()).toBe(false); expect(ACL.getPublicWriteAccess()).toBe(false); const perms = ACL.permissionsById; - expect(Object.keys(perms).length).toBe(2); + expect(Object.keys(perms).length).toBe(1); expect(perms[user.id].read).toBe(true); expect(perms[user.id].write).toBe(true); - expect(perms['*'].read).toBe(true); - expect(perms['*'].write).not.toBe(true); + expect(perms['*']).toBeUndefined(); done(); }); @@ -818,8 +871,8 @@ describe('Parse.User testing', () => { kevin.set('password', 'mypass'); await kevin.signUp(); const query = new Parse.Query(Parse.User); - const count = await query.count(); - equal(count, 2); + const count = await query.find({ useMasterKey: true }); + equal(count.length, 2); done(); }); @@ -1129,7 +1182,7 @@ describe('Parse.User testing', () => { this.synchronizedExpiration = authData.expiration_date; return true; }, - getAuthType: function () { + getAuthType() { return 'facebook'; }, deauthenticate: function () { @@ -1158,7 +1211,7 @@ describe('Parse.User testing', () => { synchronizedAuthToken: null, synchronizedExpiration: null, - authenticate: function (options) { + authenticate(options) { if (this.shouldError) { options.error(this, 'An error occurred'); } else if (this.shouldCancel) { @@ -1167,7 +1220,7 @@ describe('Parse.User testing', () => { options.success(this, this.authData); } }, - restoreAuthentication: function (authData) { + restoreAuthentication(authData) { if (!authData) { this.synchronizedUserId = null; this.synchronizedAuthToken = null; @@ -1179,10 +1232,10 @@ describe('Parse.User testing', () => { this.synchronizedExpiration = authData.expiration_date; return true; }, - getAuthType: function () { + getAuthType() { return 'myoauth'; }, - deauthenticate: function () { + deauthenticate() { this.loggedOut = true; this.restoreAuthentication(null); }, @@ -1792,7 +1845,7 @@ describe('Parse.User testing', () => { }); }); - it('should allow login with old authData token', done => { + it('should not allow login with expired authData token since allowExpiredAuthDataToken is set to false by default', async () => { const provider = { authData: { id: '12345', @@ -1813,22 +1866,12 @@ describe('Parse.User testing', () => { }; defaultConfiguration.auth.shortLivedAuth.setValidAccessToken('token'); Parse.User._registerAuthenticationProvider(provider); - Parse.User._logInWith('shortLivedAuth', {}) - .then(() => { - // Simulate a remotely expired token (like a short lived one) - // In this case, we want success as it was valid once. - // If the client needs an updated one, do lock the user out - defaultConfiguration.auth.shortLivedAuth.setValidAccessToken('otherToken'); - return Parse.User._logInWith('shortLivedAuth', {}); - }) - .then( - () => { - done(); - }, - err => { - done.fail(err); - } - ); + await Parse.User._logInWith('shortLivedAuth', {}); + // Simulate a remotely expired token (like a short lived one) + // In this case, we want success as it was valid once. + // If the client needs an updated token, do lock the user out + defaultConfiguration.auth.shortLivedAuth.setValidAccessToken('otherToken'); + await expectAsync(Parse.User._logInWith('shortLivedAuth', {})).toBeRejected(); }); it('should allow PUT request with stale auth Data', done => { @@ -2076,7 +2119,15 @@ describe('Parse.User testing', () => { }); it("querying for users doesn't get session tokens", done => { - Parse.User.signUp('finn', 'human', { foo: 'bar' }) + const user = new Parse.User(); + user.set('username', 'finn'); + user.set('password', 'human'); + user.set('foo', 'bar'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); + user + .signUp() .then(function () { return Parse.User.logOut(); }) @@ -2085,6 +2136,9 @@ describe('Parse.User testing', () => { user.set('username', 'jake'); user.set('password', 'dog'); user.set('foo', 'baz'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); return user.signUp(); }) .then(function () { @@ -2111,7 +2165,14 @@ describe('Parse.User testing', () => { }); it('querying for users only gets the expected fields', done => { - Parse.User.signUp('finn', 'human', { foo: 'bar' }).then(() => { + const user = new Parse.User(); + user.setUsername('finn'); + user.setPassword('human'); + user.set('foo', 'bar'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); + user.signUp().then(() => { request({ headers: { 'X-Parse-Application-Id': 'test', @@ -2260,37 +2321,14 @@ describe('Parse.User testing', () => { }); describe('anonymous users', () => { - beforeEach(() => { - const insensitiveCollisions = [ - 'abcdefghijklmnop', - 'Abcdefghijklmnop', - 'ABcdefghijklmnop', - 'ABCdefghijklmnop', - 'ABCDefghijklmnop', - 'ABCDEfghijklmnop', - 'ABCDEFghijklmnop', - 'ABCDEFGhijklmnop', - 'ABCDEFGHijklmnop', - 'ABCDEFGHIjklmnop', - 'ABCDEFGHIJklmnop', - 'ABCDEFGHIJKlmnop', - 'ABCDEFGHIJKLmnop', - 'ABCDEFGHIJKLMnop', - 'ABCDEFGHIJKLMnop', - 'ABCDEFGHIJKLMNop', - 'ABCDEFGHIJKLMNOp', - 'ABCDEFGHIJKLMNOP', - ]; - - // need a bunch of spare random strings per api request - spyOn(cryptoUtils, 'randomString').and.returnValues(...insensitiveCollisions); - }); - it('should not fail on case insensitive matches', async () => { - const user1 = await Parse.AnonymousUtils.logIn(); + spyOn(cryptoUtils, 'randomString').and.returnValue('abcdefghijklmnop'); + const logIn = id => Parse.User.logInWith('anonymous', { authData: { id } }); + const user1 = await logIn('test1'); const username1 = user1.get('username'); - const user2 = await Parse.AnonymousUtils.logIn(); + cryptoUtils.randomString.and.returnValue('ABCDEFGHIJKLMNOp'); + const user2 = await logIn('test2'); const username2 = user2.get('username'); expect(username1).not.toBeUndefined(); @@ -2966,6 +3004,7 @@ describe('Parse.User testing', () => { }, }); }) + .then(() => jasmine.timeout()) .then(() => { expect(emailCalled).toBe(true); expect(emailOptions).not.toBeUndefined(); @@ -3123,6 +3162,35 @@ describe('Parse.User testing', () => { .catch(done.fail); }); + it('should return current session with expired expiration date', async () => { + await Parse.User.signUp('buser', 'somepass', null); + const response = await request({ + method: 'GET', + url: 'http://localhost:8378/1/classes/_Session', + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Master-Key': 'test', + }, + }); + const body = response.data; + const id = body.results[0].objectId; + const expiresAt = new Date(new Date().setYear(2015)); + await request({ + method: 'PUT', + url: 'http://localhost:8378/1/classes/_Session/' + id, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Master-Key': 'test', + 'Content-Type': 'application/json', + }, + body: { + expiresAt: { __type: 'Date', iso: expiresAt.toISOString() }, + }, + }); + const session = await Parse.Session.current(); + expect(session.get('expiresAt')).toEqual(expiresAt); + }); + it('should not create extraneous session tokens', done => { const config = Config.get(Parse.applicationId); config.database @@ -3372,6 +3440,9 @@ describe('Parse.User testing', () => { password: 'world', email: 'test@email.com', }); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); reconfigureServer({ appName: 'unused', @@ -3448,40 +3519,128 @@ describe('Parse.User testing', () => { }); }); - it('should not allow updates to hidden fields', done => { + it('should not allow updates to hidden fields', async () => { const emailAdapter = { sendVerificationEmail: () => {}, sendPasswordResetEmail: () => Promise.resolve(), sendMail: () => Promise.resolve(), }; - const user = new Parse.User(); user.set({ username: 'hello', password: 'world', email: 'test@email.com', }); + await reconfigureServer({ + appName: 'unused', + verifyUserEmails: true, + emailAdapter: emailAdapter, + publicServerURL: 'http://localhost:8378/1', + }); + await user.signUp(); + user.set('_email_verify_token', 'bad', { ignoreValidation: true }); + await expectAsync(user.save()).toBeRejectedWith( + new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'Invalid field name: _email_verify_token.') + ); + }); - reconfigureServer({ + it('should allow updates to fields with maintenanceKey', async () => { + const emailAdapter = { + sendVerificationEmail: () => {}, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => Promise.resolve(), + }; + const user = new Parse.User(); + user.set({ + username: 'hello', + password: 'world', + email: 'test@example.com', + }); + await reconfigureServer({ appName: 'unused', + maintenanceKey: 'test2', verifyUserEmails: true, + emailVerifyTokenValidityDuration: 5, + accountLockout: { + duration: 1, + threshold: 1, + }, emailAdapter: emailAdapter, publicServerURL: 'http://localhost:8378/1', - }) - .then(() => { - return user.signUp(); - }) - .then(() => { - return Parse.User.current().set('_email_verify_token', 'bad').save(); - }) - .then(() => { - fail('Should not be able to update email verification token'); - done(); - }) - .catch(err => { - expect(err).toBeDefined(); - done(); - }); + }); + await user.signUp(); + for (let i = 0; i < 2; i++) { + try { + await Parse.User.logIn(user.getEmail(), 'abc'); + } catch (e) { + expect(e.code).toBe(Parse.Error.OBJECT_NOT_FOUND); + expect( + e.message === 'Invalid username/password.' || + e.message === + 'Your account is locked due to multiple failed login attempts. Please try again after 1 minute(s)' + ).toBeTrue(); + } + } + await Parse.User.requestPasswordReset(user.getEmail()); + const headers = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Rest-API-Key': 'rest', + 'X-Parse-Maintenance-Key': 'test2', + 'Content-Type': 'application/json', + }; + const userMaster = await request({ + method: 'GET', + url: `http://localhost:8378/1/classes/_User`, + json: true, + headers, + }).then(res => res.data.results[0]); + expect(Object.keys(userMaster).sort()).toEqual( + [ + 'ACL', + '_account_lockout_expires_at', + '_email_verify_token', + '_email_verify_token_expires_at', + '_failed_login_count', + '_perishable_token', + 'createdAt', + 'email', + 'emailVerified', + 'objectId', + 'updatedAt', + 'username', + ].sort() + ); + const toSet = { + _account_lockout_expires_at: new Date(), + _email_verify_token: 'abc', + _email_verify_token_expires_at: new Date(), + _failed_login_count: 0, + _perishable_token_expires_at: new Date(), + _perishable_token: 'abc', + }; + await request({ + method: 'PUT', + headers, + url: Parse.serverURL + '/users/' + userMaster.objectId, + json: true, + body: toSet, + }).then(res => res.data); + const update = await request({ + method: 'GET', + url: `http://localhost:8378/1/classes/_User`, + json: true, + headers, + }).then(res => res.data.results[0]); + for (const key in toSet) { + const value = toSet[key]; + if (update[key] && update[key].iso) { + expect(update[key].iso).toEqual(value.toISOString()); + } else if (value.toISOString) { + expect(update[key]).toEqual(value.toISOString()); + } else { + expect(update[key]).toEqual(value); + } + } }); it('should revoke sessions when setting paswword with masterKey (#3289)', done => { @@ -4003,6 +4162,12 @@ describe('Parse.User testing', () => { silent: true, }); + Parse.Cloud.beforeSave(Parse.User, ({ object }) => { + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + object.setACL(acl); + }); + const query = new Parse.Query(Parse.User); query.doesNotExist('foo'); const subscription = await query.subscribe(); @@ -4237,3 +4402,31 @@ describe('login as other user', () => { done(); }); }); + +describe('allowClientClassCreation option', () => { + it('should enforce boolean values', async () => { + const options = [[], 'a', '', 0, 1, {}, 'true', 'false']; + for (const option of options) { + await expectAsync(reconfigureServer({ allowClientClassCreation: option })).toBeRejected(); + } + }); + + it('should accept true value', async () => { + await reconfigureServer({ allowClientClassCreation: true }); + expect(Config.get(Parse.applicationId).allowClientClassCreation).toBe(true); + }); + + it('should accept false value', async () => { + await reconfigureServer({ allowClientClassCreation: false }); + expect(Config.get(Parse.applicationId).allowClientClassCreation).toBe(false); + }); + + it('should default false', async () => { + // remove predefined allowClientClassCreation:true on global defaultConfiguration + delete defaultConfiguration.allowClientClassCreation; + await reconfigureServer(defaultConfiguration); + expect(Config.get(Parse.applicationId).allowClientClassCreation).toBe(false); + // Need to set it back to true to avoid other test fails + defaultConfiguration.allowClientClassCreation = true; + }); +}); diff --git a/spec/PasswordPolicy.spec.js b/spec/PasswordPolicy.spec.js index 6d00ddfa28..4ea6ed2002 100644 --- a/spec/PasswordPolicy.spec.js +++ b/spec/PasswordPolicy.spec.js @@ -1677,12 +1677,19 @@ describe('Password Policy: ', () => { }); it('should not infinitely loop if maxPasswordHistory is 1 (#4918)', async () => { + const headers = { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Rest-API-Key': 'test', + 'X-Parse-Maintenance-Key': 'test2', + 'Content-Type': 'application/json', + }; const user = new Parse.User(); const query = new Parse.Query(Parse.User); await reconfigureServer({ appName: 'passwordPolicy', verifyUserEmails: false, + maintenanceKey: 'test2', passwordPolicy: { maxPasswordHistory: 1, }, @@ -1696,15 +1703,28 @@ describe('Password Policy: ', () => { user.setPassword('user2'); await user.save(); - const result1 = await query.get(user.id, { useMasterKey: true }); - expect(result1.get('_password_history').length).toBe(1); + const user1 = await query.get(user.id, { useMasterKey: true }); + expect(user1.get('_password_history')).toBeUndefined(); + + const result1 = await request({ + method: 'GET', + url: `http://localhost:8378/1/classes/_User/${user.id}`, + json: true, + headers, + }).then(res => res.data); + expect(result1._password_history.length).toBe(1); user.setPassword('user3'); await user.save(); - const result2 = await query.get(user.id, { useMasterKey: true }); - expect(result2.get('_password_history').length).toBe(1); + const result2 = await request({ + method: 'GET', + url: `http://localhost:8378/1/classes/_User/${user.id}`, + json: true, + headers, + }).then(res => res.data); + expect(result2._password_history.length).toBe(1); - expect(result1.get('_password_history')).not.toEqual(result2.get('_password_history')); + expect(result1._password_history).not.toEqual(result2._password_history); }); }); diff --git a/spec/PostgresConfigParser.spec.js b/spec/PostgresConfigParser.spec.js index 412e7b20b9..f4efc42114 100644 --- a/spec/PostgresConfigParser.spec.js +++ b/spec/PostgresConfigParser.spec.js @@ -27,13 +27,13 @@ const baseURI = 'postgres://username:password@localhost:5432/db-name'; const testfile = fs.readFileSync('./Dockerfile').toString(); const dbOptionsTest = {}; dbOptionsTest[ - `${baseURI}?ssl=true&binary=true&application_name=app_name&fallback_application_name=f_app_name&poolSize=10` + `${baseURI}?ssl=true&binary=true&application_name=app_name&fallback_application_name=f_app_name&poolSize=12` ] = { ssl: true, binary: true, application_name: 'app_name', fallback_application_name: 'f_app_name', - poolSize: 10, + max: 12, }; dbOptionsTest[`${baseURI}?ssl=&binary=aa`] = { binary: false, @@ -83,6 +83,20 @@ describe('PostgresConfigParser.getDatabaseOptionsFromURI', () => { it('sets the poolSize to 10 if the it is not a number', () => { const result = parser.getDatabaseOptionsFromURI(`${baseURI}?poolSize=sdf`); - expect(result.poolSize).toEqual(10); + expect(result.max).toEqual(10); + }); + + it('sets the max to 10 if the it is not a number', () => { + const result = parser.getDatabaseOptionsFromURI(`${baseURI}?&max=sdf`); + + expect(result.poolSize).toBeUndefined(); + expect(result.max).toEqual(10); + }); + + it('max should take precedence over poolSize', () => { + const result = parser.getDatabaseOptionsFromURI(`${baseURI}?poolSize=20&max=12`); + + expect(result.poolSize).toBeUndefined(); + expect(result.max).toEqual(12); }); }); diff --git a/spec/ProtectedFields.spec.js b/spec/ProtectedFields.spec.js index 53673e8e02..8195985dcb 100644 --- a/spec/ProtectedFields.spec.js +++ b/spec/ProtectedFields.spec.js @@ -13,6 +13,9 @@ describe('ProtectedFields', function () { user.setPassword('sekrit'); user.set('email', 'alice@aol.com'); user.set('favoriteColor', 'yellow'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); await user.save(); const fetched = await new Parse.Query(Parse.User).get(user.id); @@ -35,6 +38,9 @@ describe('ProtectedFields', function () { user.set('timeZone', 'America/Los_Angeles'); user.set('favoriteColor', 'yellow'); user.set('favoriteFood', 'pizza'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); await user.save(); const fetched = await new Parse.Query(Parse.User).get(user.id); @@ -57,6 +63,9 @@ describe('ProtectedFields', function () { user.set('timeZone', 'America/Los_Angeles'); user.set('favoriteColor', 'yellow'); user.set('favoriteFood', 'pizza'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); await user.save(); const fetched = await new Parse.Query(Parse.User).get(user.id); @@ -108,6 +117,9 @@ describe('ProtectedFields', function () { user.set('timeZone', 'America/Los_Angeles'); user.set('favoriteColor', 'yellow'); user.set('favoriteFood', 'pizza'); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + user.setACL(acl); await user.save(); const objA = await new Parse.Object('ClassA').set('foo', 'zzz').set('bar', 'yyy').save(); diff --git a/spec/PushController.spec.js b/spec/PushController.spec.js index 49613214f5..572fc9bcf9 100644 --- a/spec/PushController.spec.js +++ b/spec/PushController.spec.js @@ -26,14 +26,12 @@ const successfulIOS = function (body, installations) { return Promise.all(promises); }; -const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - const pushCompleted = async pushId => { const query = new Parse.Query('_PushStatus'); query.equalTo('objectId', pushId); let result = await query.first({ useMasterKey: true }); while (!(result && result.get('status') === 'succeeded')) { - await sleep(100); + await jasmine.timeout(); result = await query.first({ useMasterKey: true }); } }; @@ -562,7 +560,7 @@ describe('PushController', () => { }); const pushStatusId = await sendPush(payload, {}, config, auth); // it is enqueued so it can take time - await sleep(1000); + await jasmine.timeout(1000); Parse.serverURL = 'http://localhost:8378/1'; // GOOD url const result = await Parse.Push.getPushStatus(pushStatusId); expect(result).toBeDefined(); @@ -801,7 +799,7 @@ describe('PushController', () => { }); await Parse.Object.saveAll(installations); await pushController.sendPush(payload, {}, config, auth); - await sleep(1000); + await jasmine.timeout(1000); const query = new Parse.Query('_PushStatus'); const results = await query.find({ useMasterKey: true }); expect(results.length).toBe(1); @@ -856,7 +854,7 @@ describe('PushController', () => { const config = Config.get(Parse.applicationId); await Parse.Object.saveAll(installations); await pushController.sendPush(payload, {}, config, auth); - await sleep(1000); + await jasmine.timeout(1000); const query = new Parse.Query('_PushStatus'); const results = await query.find({ useMasterKey: true }); expect(results.length).toBe(1); diff --git a/spec/QueryTools.spec.js b/spec/QueryTools.spec.js index dbd3c9a5d3..8dbda98b0a 100644 --- a/spec/QueryTools.spec.js +++ b/spec/QueryTools.spec.js @@ -125,6 +125,35 @@ describe('matchesQuery', function () { expect(matchesQuery(obj, q)).toBe(false); }); + it('matches queries with eq constraint', function () { + const obj = { + objectId: 'Person2', + score: 12, + name: 'Tom', + }; + + const q1 = { + objectId: { + $eq: 'Person2', + }, + }; + + const q2 = { + score: { + $eq: 12, + }, + }; + + const q3 = { + name: { + $eq: 'Tom', + }, + }; + expect(matchesQuery(obj, q1)).toBe(true); + expect(matchesQuery(obj, q2)).toBe(true); + expect(matchesQuery(obj, q3)).toBe(true); + }); + it('matches on equality queries', function () { const day = new Date(); const location = new Parse.GeoPoint({ diff --git a/spec/RateLimit.spec.js b/spec/RateLimit.spec.js new file mode 100644 index 0000000000..3c57810702 --- /dev/null +++ b/spec/RateLimit.spec.js @@ -0,0 +1,519 @@ +const RedisCacheAdapter = require('../lib/Adapters/Cache/RedisCacheAdapter').default; +describe('rate limit', () => { + it('can limit cloud functions', async () => { + Parse.Cloud.define('test', () => 'Abc'); + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const response1 = await Parse.Cloud.run('test'); + expect(response1).toBe('Abc'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can limit cloud functions with user session token', async () => { + await Parse.User.signUp('myUser', 'password'); + Parse.Cloud.define('test', () => 'Abc'); + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const response1 = await Parse.Cloud.run('test'); + expect(response1).toBe('Abc'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can add global limit', async () => { + Parse.Cloud.define('test', () => 'Abc'); + await reconfigureServer({ + rateLimit: { + requestPath: '*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + }); + const response1 = await Parse.Cloud.run('test'); + expect(response1).toBe('Abc'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + await expectAsync(new Parse.Object('Test').save()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can limit cloud with validator', async () => { + Parse.Cloud.define('test', () => 'Abc', { + rateLimit: { + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + }); + const response1 = await Parse.Cloud.run('test'); + expect(response1).toBe('Abc'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can skip with masterKey', async () => { + Parse.Cloud.define('test', () => 'Abc'); + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const response1 = await Parse.Cloud.run('test', null, { useMasterKey: true }); + expect(response1).toBe('Abc'); + const response2 = await Parse.Cloud.run('test', null, { useMasterKey: true }); + expect(response2).toBe('Abc'); + }); + + it('should run with masterKey', async () => { + Parse.Cloud.define('test', () => 'Abc'); + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 1, + includeMasterKey: true, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const response1 = await Parse.Cloud.run('test', null, { useMasterKey: true }); + expect(response1).toBe('Abc'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can limit saving objects', async () => { + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/classes/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const obj = new Parse.Object('Test'); + await obj.save(); + await expectAsync(obj.save()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can set method to post', async () => { + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/classes/*', + requestTimeWindow: 10000, + requestCount: 1, + requestMethods: 'POST', + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const obj = new Parse.Object('Test'); + await obj.save(); + await obj.save(); + const obj2 = new Parse.Object('Test'); + await expectAsync(obj2.save()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can use a validator for post', async () => { + Parse.Cloud.beforeSave('Test', () => {}, { + rateLimit: { + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + }); + const obj = new Parse.Object('Test'); + await obj.save(); + await expectAsync(obj.save()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can use a validator for file', async () => { + Parse.Cloud.beforeSave(Parse.File, () => {}, { + rateLimit: { + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + }); + const file = new Parse.File('yolo.txt', [1, 2, 3], 'text/plain'); + await file.save(); + const file2 = new Parse.File('yolo.txt', [1, 2, 3], 'text/plain'); + await expectAsync(file2.save()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can set method to get', async () => { + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/classes/Test', + requestTimeWindow: 10000, + requestCount: 1, + requestMethods: 'GET', + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const obj = new Parse.Object('Test'); + await obj.save(); + await obj.save(); + await new Parse.Query('Test').first(); + await expectAsync(new Parse.Query('Test').first()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can use a validator', async () => { + await reconfigureServer({ silent: false }); + Parse.Cloud.beforeFind('TestObject', () => {}, { + rateLimit: { + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + }); + const obj = new Parse.Object('TestObject'); + await obj.save(); + await obj.save(); + await new Parse.Query('TestObject').first(); + await expectAsync(new Parse.Query('TestObject').first()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + await expectAsync(new Parse.Query('TestObject').get('abc')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can set method to delete', async () => { + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/classes/Test/*', + requestTimeWindow: 10000, + requestCount: 1, + requestMethods: 'DELETE', + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + const obj = new Parse.Object('Test'); + await obj.save(); + await obj.destroy(); + await expectAsync(obj.destroy()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can set beforeDelete', async () => { + const obj = new Parse.Object('TestDelete'); + await obj.save(); + Parse.Cloud.beforeDelete('TestDelete', () => {}, { + rateLimit: { + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + }); + await obj.destroy(); + await expectAsync(obj.destroy()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can set beforeLogin', async () => { + Parse.Cloud.beforeLogin(() => {}, { + rateLimit: { + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + }); + await Parse.User.signUp('myUser', 'password'); + await Parse.User.logIn('myUser', 'password'); + await expectAsync(Parse.User.logIn('myUser', 'password')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + + it('can define limits via rateLimit and define', async () => { + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 100, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + }, + ], + }); + Parse.Cloud.define('test', () => 'Abc', { + rateLimit: { + requestTimeWindow: 10000, + requestCount: 1, + includeInternalRequests: true, + }, + }); + const response1 = await Parse.Cloud.run('test'); + expect(response1).toBe('Abc'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests.') + ); + }); + + it('does not limit internal calls', async () => { + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + }, + ], + }); + Parse.Cloud.define('test1', () => 'Abc'); + Parse.Cloud.define('test2', async () => { + await Parse.Cloud.run('test1'); + await Parse.Cloud.run('test1'); + }); + await Parse.Cloud.run('test2'); + }); + + describe('zone', () => { + const middlewares = require('../lib/middlewares'); + it('can use global zone', async () => { + await reconfigureServer({ + rateLimit: { + requestPath: '*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + zone: Parse.Server.RateLimitZone.global, + }, + }); + const fakeReq = { + originalUrl: 'http://example.com/parse/', + url: 'http://example.com/', + body: { + _ApplicationId: 'test', + }, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }, + get: key => { + return fakeReq.headers[key]; + }, + }; + fakeReq.ip = '127.0.0.1'; + let fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status', 'setHeader', 'json']); + await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve)); + fakeReq.ip = '127.0.0.2'; + fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status', 'setHeader']); + let resolvingPromise; + const promise = new Promise(resolve => { + resolvingPromise = resolve; + }); + fakeRes.json = jasmine.createSpy('json').and.callFake(resolvingPromise); + middlewares.handleParseHeaders(fakeReq, fakeRes, () => { + throw 'Should not call next'; + }); + await promise; + expect(fakeRes.status).toHaveBeenCalledWith(429); + expect(fakeRes.json).toHaveBeenCalledWith({ + code: Parse.Error.CONNECTION_FAILED, + error: 'Too many requests', + }); + }); + + it('can use session zone', async () => { + await reconfigureServer({ + rateLimit: { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + zone: Parse.Server.RateLimitZone.session, + }, + }); + Parse.Cloud.define('test', () => 'Abc'); + await Parse.User.signUp('username', 'password'); + await Parse.Cloud.run('test'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + await Parse.User.logIn('username', 'password'); + await Parse.Cloud.run('test'); + }); + + it('can use user zone', async () => { + await reconfigureServer({ + rateLimit: { + requestPath: '/functions/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + zone: Parse.Server.RateLimitZone.user, + }, + }); + Parse.Cloud.define('test', () => 'Abc'); + await Parse.User.signUp('username', 'password'); + await Parse.Cloud.run('test'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + await Parse.User.logIn('username', 'password'); + await expectAsync(Parse.Cloud.run('test')).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + }); + }); + + it('can validate rateLimit', async () => { + const Config = require('../lib/Config'); + const validateRateLimit = ({ rateLimit }) => Config.validateRateLimit(rateLimit); + expect(() => + validateRateLimit({ rateLimit: 'a', requestTimeWindow: 1000, requestCount: 3 }) + ).toThrow('rateLimit must be an array or object'); + expect(() => validateRateLimit({ rateLimit: ['a'] })).toThrow( + 'rateLimit must be an array of objects' + ); + expect(() => validateRateLimit({ rateLimit: [{ requestPath: [] }] })).toThrow( + 'rateLimit.requestPath must be a string' + ); + expect(() => + validateRateLimit({ rateLimit: [{ requestTimeWindow: [], requestPath: 'a' }] }) + ).toThrow('rateLimit.requestTimeWindow must be a number'); + expect(() => + validateRateLimit({ + rateLimit: [{ requestPath: 'a', requestTimeWindow: 1000, requestCount: 3, zone: 'abc' }], + }) + ).toThrow('rateLimit.zone must be one of global, session, user, or ip'); + expect(() => + validateRateLimit({ + rateLimit: [ + { + includeInternalRequests: [], + requestTimeWindow: 1000, + requestCount: 3, + requestPath: 'a', + }, + ], + }) + ).toThrow('rateLimit.includeInternalRequests must be a boolean'); + expect(() => + validateRateLimit({ + rateLimit: [{ requestCount: [], requestTimeWindow: 1000, requestPath: 'a' }], + }) + ).toThrow('rateLimit.requestCount must be a number'); + expect(() => + validateRateLimit({ + rateLimit: [ + { errorResponseMessage: [], requestTimeWindow: 1000, requestCount: 3, requestPath: 'a' }, + ], + }) + ).toThrow('rateLimit.errorResponseMessage must be a string'); + expect(() => + validateRateLimit({ rateLimit: [{ requestCount: 3, requestPath: 'abc' }] }) + ).toThrow('rateLimit.requestTimeWindow must be defined'); + expect(() => + validateRateLimit({ rateLimit: [{ requestTimeWindow: 3, requestPath: 'abc' }] }) + ).toThrow('rateLimit.requestCount must be defined'); + expect(() => + validateRateLimit({ rateLimit: [{ requestTimeWindow: 3, requestCount: 'abc' }] }) + ).toThrow('rateLimit.requestPath must be defined'); + await expectAsync( + reconfigureServer({ + rateLimit: [{ requestTimeWindow: 3, requestCount: 1, path: 'abc', requestPath: 'a' }], + }) + ).toBeRejectedWith(`Invalid rate limit option "path"`); + }); + describe_only(() => { + return process.env.PARSE_SERVER_TEST_CACHE === 'redis'; + })('with RedisCache', function () { + it('does work with cache', async () => { + await reconfigureServer({ + rateLimit: [ + { + requestPath: '/classes/*', + requestTimeWindow: 10000, + requestCount: 1, + errorResponseMessage: 'Too many requests', + includeInternalRequests: true, + redisUrl: 'redis://localhost:6379', + }, + ], + }); + const obj = new Parse.Object('Test'); + await obj.save(); + await expectAsync(obj.save()).toBeRejectedWith( + new Parse.Error(Parse.Error.CONNECTION_FAILED, 'Too many requests') + ); + const cache = new RedisCacheAdapter(); + await cache.connect(); + const value = await cache.get('rl:127.0.0.1'); + expect(value).toEqual(2); + const ttl = await cache.client.ttl('rl:127.0.0.1'); + expect(ttl).toEqual(10); + }); + }); +}); diff --git a/spec/ReadPreferenceOption.spec.js b/spec/ReadPreferenceOption.spec.js index 535c35c8b0..67b976674b 100644 --- a/spec/ReadPreferenceOption.spec.js +++ b/spec/ReadPreferenceOption.spec.js @@ -625,7 +625,7 @@ describe_only_db('mongo')('Read preference option', () => { spyOn(Collection.prototype, 'aggregate').and.callThrough(); // Query const query = new Parse.Query('MyObject'); - const results = await query.aggregate([{ match: { boolKey: false } }]); + const results = await query.aggregate([{ $match: { boolKey: false } }]); // Validate expect(results.length).toBe(1); let readPreference = null; @@ -678,7 +678,7 @@ describe_only_db('mongo')('Read preference option', () => { // Query const query = new Parse.Query('MyObject'); query.readPreference('SECONDARY'); - const results = await query.aggregate([{ match: { boolKey: false } }]); + const results = await query.aggregate([{ $match: { boolKey: false } }]); // Validate expect(results.length).toBe(1); let readPreference = null; diff --git a/spec/RedisCacheAdapter.spec.js b/spec/RedisCacheAdapter.spec.js index 952d23eb0d..9b88e857c4 100644 --- a/spec/RedisCacheAdapter.spec.js +++ b/spec/RedisCacheAdapter.spec.js @@ -19,23 +19,22 @@ describe_only(() => { beforeEach(async () => { cache = new RedisCacheAdapter(null, 100); + await cache.connect(); await cache.clear(); }); - it('should get/set/clear', done => { + it('should get/set/clear', async () => { const cacheNaN = new RedisCacheAdapter({ ttl: NaN, }); - - cacheNaN - .put(KEY, VALUE) - .then(() => cacheNaN.get(KEY)) - .then(value => expect(value).toEqual(VALUE)) - .then(() => cacheNaN.clear()) - .then(() => cacheNaN.get(KEY)) - .then(value => expect(value).toEqual(null)) - .then(() => cacheNaN.clear()) - .then(done); + await cacheNaN.connect(); + await cacheNaN.put(KEY, VALUE); + let value = await cacheNaN.get(KEY); + expect(value).toEqual(VALUE); + await cacheNaN.clear(); + value = await cacheNaN.get(KEY); + expect(value).toEqual(null); + await cacheNaN.clear(); }); it('should expire after ttl', done => { @@ -100,7 +99,7 @@ describe_only(() => { it('handleShutdown, close connection', async () => { await cache.handleShutdown(); setTimeout(() => { - expect(cache.client.connected).toBe(false); + expect(cache.client.isOpen).toBe(false); }, 0); }); }); @@ -122,8 +121,9 @@ describe_only(() => { return Object.keys(cache.queue.queue).length; } - it('it should clear completed operations from queue', done => { + it('it should clear completed operations from queue', async done => { const cache = new RedisCacheAdapter({ ttl: NaN }); + await cache.connect(); // execute a bunch of operations in sequence let promise = Promise.resolve(); @@ -144,8 +144,9 @@ describe_only(() => { promise.then(() => expect(getQueueCount(cache)).toEqual(0)).then(done); }); - it('it should count per key chained operations correctly', done => { + it('it should count per key chained operations correctly', async done => { const cache = new RedisCacheAdapter({ ttl: NaN }); + await cache.connect(); let key1Promise = Promise.resolve(); let key2Promise = Promise.resolve(); @@ -166,4 +167,18 @@ describe_only(() => { .then(() => expect(getQueueCount(cache)).toEqual(0)) .then(done); }); + + it('should start and connect cache adapter', async () => { + const server = await reconfigureServer({ + cacheAdapter: { + module: `${__dirname.replace('/spec', '')}/lib/Adapters/Cache/RedisCacheAdapter`, + options: { + url: 'redis://127.0.0.1:6379/1', + }, + }, + }); + const symbol = Object.getOwnPropertySymbols(server.config.cacheController); + const client = server.config.cacheController[symbol[0]].client; + expect(client.isOpen).toBeTrue(); + }); }); diff --git a/spec/RedisPubSub.spec.js b/spec/RedisPubSub.spec.js index c7def313cd..b68448ef51 100644 --- a/spec/RedisPubSub.spec.js +++ b/spec/RedisPubSub.spec.js @@ -15,7 +15,8 @@ describe('RedisPubSub', function () { }); const redis = require('redis'); - expect(redis.createClient).toHaveBeenCalledWith('redisAddress', { + expect(redis.createClient).toHaveBeenCalledWith({ + url: 'redisAddress', socket_keepalive: true, no_ready_check: true, }); @@ -28,7 +29,8 @@ describe('RedisPubSub', function () { }); const redis = require('redis'); - expect(redis.createClient).toHaveBeenCalledWith('redisAddress', { + expect(redis.createClient).toHaveBeenCalledWith({ + url: 'redisAddress', socket_keepalive: true, no_ready_check: true, }); diff --git a/spec/RegexVulnerabilities.spec.js b/spec/RegexVulnerabilities.spec.js index 62af4f04e2..5d3bdf254d 100644 --- a/spec/RegexVulnerabilities.spec.js +++ b/spec/RegexVulnerabilities.spec.js @@ -19,6 +19,7 @@ const publicServerURL = 'http://localhost:8378/1'; describe('Regex Vulnerabilities', function () { beforeEach(async function () { await reconfigureServer({ + maintenanceKey: 'test2', verifyUserEmails: true, emailAdapter, appName, @@ -98,11 +99,20 @@ describe('Regex Vulnerabilities', function () { it('should work with plain token', async function () { expect(this.user.get('emailVerified')).toEqual(false); + const current = await request({ + method: 'GET', + url: `http://localhost:8378/1/classes/_User/${this.user.id}`, + json: true, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Rest-API-Key': 'test', + 'X-Parse-Maintenance-Key': 'test2', + 'Content-Type': 'application/json', + }, + }).then(res => res.data); // It should work await request({ - url: `${serverURL}/apps/test/verify_email?username=someemail@somedomain.com&token=${this.user.get( - '_email_verify_token' - )}`, + url: `${serverURL}/apps/test/verify_email?username=someemail@somedomain.com&token=${current._email_verify_token}`, method: 'GET', }); await this.user.fetch({ useMasterKey: true }); @@ -164,8 +174,18 @@ describe('Regex Vulnerabilities', function () { email: 'someemail@somedomain.com', }), }); - await this.user.fetch({ useMasterKey: true }); - const token = this.user.get('_perishable_token'); + const current = await request({ + method: 'GET', + url: `http://localhost:8378/1/classes/_User/${this.user.id}`, + json: true, + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-Rest-API-Key': 'test', + 'X-Parse-Maintenance-Key': 'test2', + 'Content-Type': 'application/json', + }, + }).then(res => res.data); + const token = current._perishable_token; const passwordResetResponse = await request({ url: `${serverURL}/apps/test/request_password_reset?username=someemail@somedomain.com&token=${token}`, method: 'GET', diff --git a/spec/RestQuery.spec.js b/spec/RestQuery.spec.js index 02af2fc576..023d3b4790 100644 --- a/spec/RestQuery.spec.js +++ b/spec/RestQuery.spec.js @@ -96,6 +96,7 @@ describe('rest query', () => { let user = { username: 'aUsername', password: 'aPassword', + ACL: { '*': { read: true } }, }; const activity = { type: 'comment', @@ -398,15 +399,16 @@ describe('RestQuery.each', () => { } const config = Config.get('test'); await Parse.Object.saveAll(objects); - const query = new RestQuery( + const query = await RestQuery({ + method: RestQuery.Method.find, config, - auth.master(config), - 'Object', - { value: { $gt: 2 } }, - { limit: 2 } - ); + auth: auth.master(config), + className: 'Object', + restWhere: { value: { $gt: 2 } }, + restOptions: { limit: 2 }, + }); const spy = spyOn(query, 'execute').and.callThrough(); - const classSpy = spyOn(RestQuery.prototype, 'execute').and.callThrough(); + const classSpy = spyOn(RestQuery._UnsafeRestQuery.prototype, 'execute').and.callThrough(); const results = []; await query.each(result => { expect(result.value).toBeGreaterThan(2); @@ -437,34 +439,37 @@ describe('RestQuery.each', () => { * Two queries needed since objectId are sorted and we can't know which one * going to be the first and then skip by the $gt added by each */ - const queryOne = new RestQuery( + const queryOne = await RestQuery({ + method: RestQuery.Method.get, config, - auth.master(config), - 'Letter', - { + auth: auth.master(config), + className: 'Letter', + restWhere: { numbers: { __type: 'Pointer', className: 'Number', objectId: object1.id, }, }, - { limit: 1 } - ); - const queryTwo = new RestQuery( + restOptions: { limit: 1 }, + }); + + const queryTwo = await RestQuery({ + method: RestQuery.Method.get, config, - auth.master(config), - 'Letter', - { + auth: auth.master(config), + className: 'Letter', + restWhere: { numbers: { __type: 'Pointer', className: 'Number', objectId: object2.id, }, }, - { limit: 1 } - ); + restOptions: { limit: 1 }, + }); - const classSpy = spyOn(RestQuery.prototype, 'execute').and.callThrough(); + const classSpy = spyOn(RestQuery._UnsafeRestQuery.prototype, 'execute').and.callThrough(); const resultsOne = []; const resultsTwo = []; await queryOne.each(result => { diff --git a/spec/SchemaPerformance.spec.js b/spec/SchemaPerformance.spec.js index 0471871c54..17238b0ed6 100644 --- a/spec/SchemaPerformance.spec.js +++ b/spec/SchemaPerformance.spec.js @@ -204,4 +204,58 @@ describe('Schema Performance', function () { ); expect(getAllSpy.calls.count()).toBe(2); }); + + it('does reload with schemaCacheTtl', async () => { + const databaseURI = + process.env.PARSE_SERVER_TEST_DB === 'postgres' + ? process.env.PARSE_SERVER_TEST_DATABASE_URI + : 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase'; + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + silent: false, + databaseOptions: { schemaCacheTtl: 1000 }, + }); + const SchemaController = require('../lib/Controllers/SchemaController').SchemaController; + const spy = spyOn(SchemaController.prototype, 'reloadData').and.callThrough(); + Object.defineProperty(spy, 'reloadCalls', { + get: () => spy.calls.all().filter(call => call.args[0].clearCache).length, + }); + + const object = new TestObject(); + object.set('foo', 'bar'); + await object.save(); + + spy.calls.reset(); + + object.set('foo', 'bar'); + await object.save(); + + expect(spy.reloadCalls).toBe(0); + + await new Promise(resolve => setTimeout(resolve, 1100)); + + object.set('foo', 'bar'); + await object.save(); + + expect(spy.reloadCalls).toBe(1); + }); + + it('cannot set invalid databaseOptions', async () => { + const expectError = async (key, value, expected) => + expectAsync( + reconfigureServer({ databaseAdapter: undefined, databaseOptions: { [key]: value } }) + ).toBeRejectedWith(`databaseOptions.${key} must be a ${expected}`); + for (const databaseOptions of [[], 0, 'string']) { + await expectAsync( + reconfigureServer({ databaseAdapter: undefined, databaseOptions }) + ).toBeRejectedWith(`databaseOptions must be an object`); + } + for (const value of [null, 0, 'string', {}, []]) { + await expectError('enableSchemaHooks', value, 'boolean'); + } + for (const value of [null, false, 'string', {}, []]) { + await expectError('schemaCacheTtl', value, 'number'); + } + }); }); diff --git a/spec/SessionTokenCache.spec.js b/spec/SessionTokenCache.spec.js index de1b101c56..6b3c83df62 100644 --- a/spec/SessionTokenCache.spec.js +++ b/spec/SessionTokenCache.spec.js @@ -47,7 +47,7 @@ describe('SessionTokenCache', function () { sessionTokenCache.getUserId('sessionToken').then(userIdFromCache => { expect(userIdFromCache).toBe('userId'); - expect(sessionTokenCache.cache.length).toBe(1); + expect(sessionTokenCache.cache.size).toBe(1); done(); }); }); diff --git a/spec/UserController.spec.js b/spec/UserController.spec.js index 6bcc454baf..03c979abe6 100644 --- a/spec/UserController.spec.js +++ b/spec/UserController.spec.js @@ -1,55 +1,76 @@ -const UserController = require('../lib/Controllers/UserController').UserController; const emailAdapter = require('./support/MockEmailAdapter'); +const Config = require('../lib/Config'); +const Auth = require('../lib/Auth'); describe('UserController', () => { - const user = { - _email_verify_token: 'testToken', - username: 'testUser', - email: 'test@example.com', - }; - describe('sendVerificationEmail', () => { describe('parseFrameURL not provided', () => { - it('uses publicServerURL', async done => { + it('uses publicServerURL', async () => { await reconfigureServer({ publicServerURL: 'http://www.example.com', customPages: { parseFrameURL: undefined, }, + verifyUserEmails: true, + emailAdapter, + appName: 'test', }); + + let emailOptions; emailAdapter.sendVerificationEmail = options => { - expect(options.link).toEqual( - 'http://www.example.com/apps/test/verify_email?token=testToken&username=testUser' - ); - emailAdapter.sendVerificationEmail = () => Promise.resolve(); - done(); + emailOptions = options; + return Promise.resolve(); }; - const userController = new UserController(emailAdapter, 'test', { - verifyUserEmails: true, - }); - userController.sendVerificationEmail(user); + + const username = 'verificationUser'; + const user = new Parse.User(); + user.setUsername(username); + user.setPassword('pass'); + user.setEmail('verification@example.com'); + await user.signUp(); + + const config = Config.get('test'); + const rawUser = await config.database.find('_User', { username }, {}, Auth.maintenance(config)); + const rawUsername = rawUser[0].username; + const rawToken = rawUser[0]._email_verify_token; + expect(rawToken).toBeDefined(); + expect(rawUsername).toBe(username); + expect(emailOptions.link).toEqual(`http://www.example.com/apps/test/verify_email?token=${rawToken}&username=${username}`); }); }); describe('parseFrameURL provided', () => { - it('uses parseFrameURL and includes the destination in the link parameter', async done => { + it('uses parseFrameURL and includes the destination in the link parameter', async () => { await reconfigureServer({ publicServerURL: 'http://www.example.com', customPages: { parseFrameURL: 'http://someother.example.com/handle-parse-iframe', }, + verifyUserEmails: true, + emailAdapter, + appName: 'test', }); + + let emailOptions; emailAdapter.sendVerificationEmail = options => { - expect(options.link).toEqual( - 'http://someother.example.com/handle-parse-iframe?link=%2Fapps%2Ftest%2Fverify_email&token=testToken&username=testUser' - ); - emailAdapter.sendVerificationEmail = () => Promise.resolve(); - done(); + emailOptions = options; + return Promise.resolve(); }; - const userController = new UserController(emailAdapter, 'test', { - verifyUserEmails: true, - }); - userController.sendVerificationEmail(user); + + const username = 'verificationUser'; + const user = new Parse.User(); + user.setUsername(username); + user.setPassword('pass'); + user.setEmail('verification@example.com'); + await user.signUp(); + + const config = Config.get('test'); + const rawUser = await config.database.find('_User', { username }, {}, Auth.maintenance(config)); + const rawUsername = rawUser[0].username; + const rawToken = rawUser[0]._email_verify_token; + expect(rawToken).toBeDefined(); + expect(rawUsername).toBe(username); + expect(emailOptions.link).toEqual(`http://someother.example.com/handle-parse-iframe?link=%2Fapps%2Ftest%2Fverify_email&token=${rawToken}&username=${username}`); }); }); }); diff --git a/spec/UserPII.spec.js b/spec/UserPII.spec.js index 87bfe15e4e..5416068f0e 100644 --- a/spec/UserPII.spec.js +++ b/spec/UserPII.spec.js @@ -16,7 +16,9 @@ describe('Personally Identifiable Information', () => { await reconfigureServer(); user = await Parse.User.signUp('tester', 'abc'); user = await Parse.User.logIn(user.get('username'), 'abc'); - await user.set('email', EMAIL).set('zip', ZIP).set('ssn', SSN).save(); + const acl = new Parse.ACL(); + acl.setPublicReadAccess(true); + await user.set('email', EMAIL).set('zip', ZIP).set('ssn', SSN).setACL(acl).save(); done(); }); diff --git a/spec/ValidationAndPasswordsReset.spec.js b/spec/ValidationAndPasswordsReset.spec.js index d7cc72c7b0..fb163ad567 100644 --- a/spec/ValidationAndPasswordsReset.spec.js +++ b/spec/ValidationAndPasswordsReset.spec.js @@ -51,6 +51,7 @@ describe('Custom Pages, Email Verification, Password Reset', () => { user.setUsername('zxcv'); user.setEmail('testIfEnabled@parse.com'); await user.signUp(); + await jasmine.timeout(); expect(emailAdapter.sendVerificationEmail).toHaveBeenCalled(); user.fetch().then(() => { expect(user.get('emailVerified')).toEqual(false); @@ -137,6 +138,7 @@ describe('Custom Pages, Email Verification, Password Reset', () => { spyOn(emailAdapter, 'sendVerificationEmail').and.callFake(options => { expect(options.link).not.toBeNull(); expect(options.link).not.toMatch(/token=undefined/); + expect(options.link).not.toMatch(/username=undefined/); Promise.resolve(); }); const user = new Parse.User(); @@ -183,6 +185,7 @@ describe('Custom Pages, Email Verification, Password Reset', () => { user.setUsername('zxcv'); user.set('email', 'testSendSimpleAdapter@parse.com'); await user.signUp(); + await jasmine.timeout(); expect(calls).toBe(1); user .fetch() @@ -242,8 +245,67 @@ describe('Custom Pages, Email Verification, Password Reset', () => { }); }); - it('allows user to login only after user clicks on the link to confirm email address if preventLoginWithUnverifiedEmail is set to true', done => { + it('prevents user from signup and login if email is not verified and preventLoginWithUnverifiedEmail is set to function returning true', async () => { + await reconfigureServer({ + appName: 'test', + publicServerURL: 'http://localhost:1337/1', + verifyUserEmails: async () => true, + preventLoginWithUnverifiedEmail: async () => true, + preventSignupWithUnverifiedEmail: true, + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + }); + + const user = new Parse.User(); + user.setPassword('asdf'); + user.setUsername('zxcv'); + user.set('email', 'testInvalidConfig@parse.com'); + const signupRes = await user.signUp(null).catch(e => e); + expect(signupRes.message).toEqual('User email is not verified.'); + + const loginRes = await Parse.User.logIn('zxcv', 'asdf').catch(e => e); + expect(loginRes.message).toEqual('User email is not verified.'); + }); + + it('provides function arguments in verifyUserEmails on login', async () => { const user = new Parse.User(); + user.setUsername('user'); + user.setPassword('pass'); + user.set('email', 'test@example.com'); + await user.signUp(); + + const verifyUserEmails = { + method: async (params) => { + expect(params.object).toBeInstanceOf(Parse.User); + expect(params.ip).toBeDefined(); + expect(params.master).toBeDefined(); + expect(params.installationId).toBeDefined(); + return true; + }, + }; + const verifyUserEmailsSpy = spyOn(verifyUserEmails, 'method').and.callThrough(); + await reconfigureServer({ + appName: 'test', + publicServerURL: 'http://localhost:1337/1', + verifyUserEmails: verifyUserEmails.method, + preventLoginWithUnverifiedEmail: verifyUserEmails.method, + preventSignupWithUnverifiedEmail: true, + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + }); + + const res = await Parse.User.logIn('user', 'pass').catch(e => e); + expect(res.code).toBe(205); + expect(verifyUserEmailsSpy).toHaveBeenCalledTimes(2); + }); + + it('allows user to login only after user clicks on the link to confirm email address if preventLoginWithUnverifiedEmail is set to true', async () => { let sendEmailOptions; const emailAdapter = { sendVerificationEmail: options => { @@ -252,59 +314,33 @@ describe('Custom Pages, Email Verification, Password Reset', () => { sendPasswordResetEmail: () => Promise.resolve(), sendMail: () => {}, }; - reconfigureServer({ + await reconfigureServer({ appName: 'emailing app', verifyUserEmails: true, preventLoginWithUnverifiedEmail: true, emailAdapter: emailAdapter, publicServerURL: 'http://localhost:8378/1', - }) - .then(() => { - user.setPassword('other-password'); - user.setUsername('user'); - user.set('email', 'user@parse.com'); - return user.signUp(); - }) - .then(() => { - expect(sendEmailOptions).not.toBeUndefined(); - request({ - url: sendEmailOptions.link, - followRedirects: false, - }).then(response => { - expect(response.status).toEqual(302); - expect(response.text).toEqual( - 'Found. Redirecting to http://localhost:8378/1/apps/verify_email_success.html?username=user' - ); - user - .fetch() - .then( - () => { - expect(user.get('emailVerified')).toEqual(true); - - Parse.User.logIn('user', 'other-password').then( - user => { - expect(typeof user).toBe('object'); - expect(user.get('emailVerified')).toBe(true); - done(); - }, - () => { - fail('login should have succeeded'); - done(); - } - ); - }, - err => { - jfail(err); - fail('this should not fail'); - done(); - } - ) - .catch(err => { - jfail(err); - done(); - }); - }); - }); + }); + let user = new Parse.User(); + user.setPassword('other-password'); + user.setUsername('user'); + user.set('email', 'user@example.com'); + await user.signUp(); + await jasmine.timeout(); + expect(sendEmailOptions).not.toBeUndefined(); + const response = await request({ + url: sendEmailOptions.link, + followRedirects: false, + }); + expect(response.status).toEqual(302); + expect(response.text).toEqual( + 'Found. Redirecting to http://localhost:8378/1/apps/verify_email_success.html?username=user' + ); + user = await new Parse.Query(Parse.User).first({ useMasterKey: true }); + expect(user.get('emailVerified')).toEqual(true); + user = await Parse.User.logIn('user', 'other-password'); + expect(typeof user).toBe('object'); + expect(user.get('emailVerified')).toBe(true); }); it('allows user to login if email is not verified but preventLoginWithUnverifiedEmail is set to false', done => { @@ -345,6 +381,35 @@ describe('Custom Pages, Email Verification, Password Reset', () => { }); }); + it('does not allow signup with preventSignupWithUnverified', async () => { + let sendEmailOptions; + const emailAdapter = { + sendVerificationEmail: options => { + sendEmailOptions = options; + }, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => {}, + }; + await reconfigureServer({ + appName: 'test', + publicServerURL: 'http://localhost:1337/1', + verifyUserEmails: true, + preventLoginWithUnverifiedEmail: true, + preventSignupWithUnverifiedEmail: true, + emailAdapter, + }); + const newUser = new Parse.User(); + newUser.setPassword('asdf'); + newUser.setUsername('zxcv'); + newUser.set('email', 'test@example.com'); + await expectAsync(newUser.signUp()).toBeRejectedWith( + new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, 'User email is not verified.') + ); + const user = await new Parse.Query(Parse.User).first({ useMasterKey: true }); + expect(user).toBeDefined(); + expect(sendEmailOptions).toBeDefined(); + }); + it('fails if you include an emailAdapter, set a publicServerURL, but have no appName and send a password reset email', done => { reconfigureServer({ appName: undefined, @@ -573,6 +638,7 @@ describe('Custom Pages, Email Verification, Password Reset', () => { user.setUsername('zxcv'); user.set('email', 'user@parse.com'); await user.signUp(); + await jasmine.timeout(); expect(emailSent).toBe(true); done(); }); @@ -600,6 +666,7 @@ describe('Custom Pages, Email Verification, Password Reset', () => { user.set('email', 'user@parse.com'); return user.signUp(); }) + .then(() => jasmine.timeout()) .then(() => { expect(sendEmailOptions).not.toBeUndefined(); request({ @@ -1082,4 +1149,43 @@ describe('Custom Pages, Email Verification, Password Reset', () => { done(); }); }); + + it('should throw on an invalid reset password', async () => { + await reconfigureServer({ + appName: 'coolapp', + publicServerURL: 'http://localhost:1337/1', + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + passwordPolicy: { + resetPasswordSuccessOnInvalidEmail: false, + }, + }); + + await expectAsync(Parse.User.requestPasswordReset('test@example.com')).toBeRejectedWith( + new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'A user with that email does not exist.') + ); + }); + + it('validate resetPasswordSuccessonInvalidEmail', async () => { + const invalidValues = [[], {}, 1, 'string']; + for (const value of invalidValues) { + await expectAsync( + reconfigureServer({ + appName: 'coolapp', + publicServerURL: 'http://localhost:1337/1', + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + passwordPolicy: { + resetPasswordSuccessOnInvalidEmail: value, + }, + }) + ).toBeRejectedWith('resetPasswordSuccessOnInvalidEmail must be a boolean value'); + } + }); }); diff --git a/spec/VerifyUserPassword.spec.js b/spec/VerifyUserPassword.spec.js index 6734dcdb71..3d15a25e15 100644 --- a/spec/VerifyUserPassword.spec.js +++ b/spec/VerifyUserPassword.spec.js @@ -353,8 +353,9 @@ describe('Verify User Password', () => { done(); }); }); - it('fails to verify password when preventLoginWithUnverifiedEmail is set to true REST API', done => { - reconfigureServer({ + + it('fails to verify password when preventLoginWithUnverifiedEmail is set to true REST API', async () => { + await reconfigureServer({ publicServerURL: 'http://localhost:8378/', appName: 'emailVerify', verifyUserEmails: true, @@ -364,28 +365,21 @@ describe('Verify User Password', () => { apiKey: 'k', domain: 'd', }), - }) - .then(() => { - const user = new Parse.User(); - return user.save({ - username: 'unverified-user', - password: 'mypass', - email: 'unverified-email@user.com', - }); - }) - .then(() => { - return verifyPassword('unverified-email@user.com', 'mypass', true); - }) - .then(res => { - expect(res.status).toBe(400); - expect(res.text).toMatch('{"code":205,"error":"User email is not verified."}'); - done(); - }) - .catch(err => { - fail(err); - done(); - }); + }); + const user = new Parse.User(); + await user.save({ + username: 'unverified-user', + password: 'mypass', + email: 'unverified-email@example.com', + }); + const res = await verifyPassword('unverified-email@example.com', 'mypass', true); + expect(res.status).toBe(400); + expect(res.data).toEqual({ + code: Parse.Error.EMAIL_NOT_FOUND, + error: 'User email is not verified.', + }); }); + it('verify password lock account if failed verify password attempts are above threshold', done => { reconfigureServer({ appName: 'lockout threshold', @@ -591,4 +585,83 @@ describe('Verify User Password', () => { done(); }); }); + + it('verify password of user with unverified email with master key and ignoreEmailVerification=true', async () => { + await reconfigureServer({ + publicServerURL: 'http://localhost:8378/', + appName: 'emailVerify', + verifyUserEmails: true, + preventLoginWithUnverifiedEmail: true, + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + }); + + const user = new Parse.User(); + user.setUsername('user'); + user.setPassword('pass'); + user.setEmail('test@example.com'); + await user.signUp(); + + const { data: res } = await request({ + method: 'POST', + url: Parse.serverURL + '/verifyPassword', + headers: { + 'X-Parse-Master-Key': Parse.masterKey, + 'X-Parse-Application-Id': Parse.applicationId, + 'X-Parse-REST-API-Key': 'rest', + 'Content-Type': 'application/json', + }, + body: { + username: 'user', + password: 'pass', + ignoreEmailVerification: true, + }, + json: true, + }); + expect(res.objectId).toBe(user.id); + expect(Object.prototype.hasOwnProperty.call(res, 'sessionToken')).toEqual(false); + expect(Object.prototype.hasOwnProperty.call(res, 'password')).toEqual(false); + }); + + it('fails to verify password of user with unverified email with master key and ignoreEmailVerification=false', async () => { + await reconfigureServer({ + publicServerURL: 'http://localhost:8378/', + appName: 'emailVerify', + verifyUserEmails: true, + preventLoginWithUnverifiedEmail: true, + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + }); + + const user = new Parse.User(); + user.setUsername('user'); + user.setPassword('pass'); + user.setEmail('test@example.com'); + await user.signUp(); + + const res = await request({ + method: 'POST', + url: Parse.serverURL + '/verifyPassword', + headers: { + 'X-Parse-Master-Key': Parse.masterKey, + 'X-Parse-Application-Id': Parse.applicationId, + 'X-Parse-REST-API-Key': 'rest', + 'Content-Type': 'application/json', + }, + body: { + username: 'user', + password: 'pass', + ignoreEmailVerification: false, + }, + json: true, + }).catch(e => e); + expect(res.status).toBe(400); + expect(res.text).toMatch(/User email is not verified/); + }); }); diff --git a/spec/batch.spec.js b/spec/batch.spec.js index 8c3baebcc4..8367c70f61 100644 --- a/spec/batch.spec.js +++ b/spec/batch.spec.js @@ -1,6 +1,5 @@ const batch = require('../lib/batch'); const request = require('../lib/request'); -const semver = require('semver'); const TestUtils = require('../lib/TestUtils'); const originalURL = '/parse/batch'; @@ -206,19 +205,13 @@ describe('batch', () => { }); if ( - (semver.satisfies(process.env.MONGODB_VERSION, '>=4.0.4') && - process.env.MONGODB_TOPOLOGY === 'replicaset' && - process.env.MONGODB_STORAGE_ENGINE === 'wiredTiger') || + process.env.MONGODB_TOPOLOGY === 'replicaset' || process.env.PARSE_SERVER_TEST_DB === 'postgres' ) { describe('transactions', () => { beforeEach(async () => { await TestUtils.destroyAllDataPermanently(true); - if ( - semver.satisfies(process.env.MONGODB_VERSION, '>=4.0.4') && - process.env.MONGODB_TOPOLOGY === 'replicaset' && - process.env.MONGODB_STORAGE_ENGINE === 'wiredTiger' - ) { + if (process.env.MONGODB_TOPOLOGY === 'replicaset') { await reconfigureServer({ databaseAdapter: undefined, databaseURI: diff --git a/spec/cloud/cloudCodeModuleFile.js b/spec/cloud/cloudCodeModuleFile.js new file mode 100644 index 0000000000..a62b4fcc24 --- /dev/null +++ b/spec/cloud/cloudCodeModuleFile.js @@ -0,0 +1,3 @@ +Parse.Cloud.define('cloudCodeInFile', () => { + return 'It is possible to define cloud code in a file.'; +}); diff --git a/spec/configs/CLIConfigAuth.json b/spec/configs/CLIConfigAuth.json new file mode 100644 index 0000000000..37a2a5f373 --- /dev/null +++ b/spec/configs/CLIConfigAuth.json @@ -0,0 +1,11 @@ +{ + "appName": "test", + "appId": "test", + "masterKey": "test", + "logLevel": "error", + "auth": { + "facebook": { + "appIds": "test" + } + } +} diff --git a/spec/helper.js b/spec/helper.js index f769c0f521..802dc90893 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -50,16 +50,19 @@ const { VolatileClassesSchemas } = require('../lib/Controllers/SchemaController' const mongoURI = 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase'; const postgresURI = 'postgres://localhost:5432/parse_server_postgres_adapter_test_database'; let databaseAdapter; +let databaseURI; // need to bind for mocking mocha if (process.env.PARSE_SERVER_TEST_DB === 'postgres') { + databaseURI = process.env.PARSE_SERVER_TEST_DATABASE_URI || postgresURI; databaseAdapter = new PostgresStorageAdapter({ - uri: process.env.PARSE_SERVER_TEST_DATABASE_URI || postgresURI, + uri: databaseURI, collectionPrefix: 'test_', }); } else { + databaseURI = mongoURI; databaseAdapter = new MongoStorageAdapter({ - uri: mongoURI, + uri: databaseURI, collectionPrefix: 'test_', }); } @@ -100,9 +103,10 @@ const defaultConfiguration = { restAPIKey: 'rest', webhookKey: 'hook', masterKey: 'test', + maintenanceKey: 'testing', readOnlyMasterKey: 'read-only-test', fileKey: 'test', - directAccess: false, + directAccess: true, silent, logLevel, fileUpload: { @@ -125,6 +129,7 @@ const defaultConfiguration = { }, shortLivedAuth: mockShortLivedAuth(), }, + allowClientClassCreation: true, }; if (process.env.PARSE_SERVER_TEST_CACHE === 'redis') { @@ -148,47 +153,33 @@ let server; let didChangeConfiguration = false; // Allows testing specific configurations of Parse Server -const reconfigureServer = (changedConfiguration = {}) => { - return new Promise((resolve, reject) => { - if (server) { - return server.close(() => { - server = undefined; - reconfigureServer(changedConfiguration).then(resolve, reject); - }); - } - try { - let parseServer = undefined; - didChangeConfiguration = Object.keys(changedConfiguration).length !== 0; - const newConfiguration = Object.assign({}, defaultConfiguration, changedConfiguration, { - serverStartComplete: error => { - if (error) { - reject(error); - } else { - Parse.CoreManager.setRESTController(RESTController); - resolve(parseServer); - } - }, - mountPath: '/1', - port, - }); - cache.clear(); - parseServer = ParseServer.start(newConfiguration); - parseServer.expressApp.use('/1', err => { - console.error(err); - fail('should not call next'); - }); - server = parseServer.server; - server.on('connection', connection => { - const key = `${connection.remoteAddress}:${connection.remotePort}`; - openConnections[key] = connection; - connection.on('close', () => { - delete openConnections[key]; - }); - }); - } catch (error) { - reject(error); - } +const reconfigureServer = async (changedConfiguration = {}) => { + if (server) { + await new Promise(resolve => server.close(resolve)); + server = undefined; + return reconfigureServer(changedConfiguration); + } + didChangeConfiguration = Object.keys(changedConfiguration).length !== 0; + const newConfiguration = Object.assign({}, defaultConfiguration, changedConfiguration, { + mountPath: '/1', + port, + }); + cache.clear(); + const parseServer = await ParseServer.startApp(newConfiguration); + server = parseServer.server; + Parse.CoreManager.setRESTController(RESTController); + parseServer.expressApp.use('/1', err => { + console.error(err); + fail('should not call next'); + }); + server.on('connection', connection => { + const key = `${connection.remoteAddress}:${connection.remotePort}`; + openConnections[key] = connection; + connection.on('close', () => { + delete openConnections[key]; + }); }); + return parseServer; }; // Set up a Parse client to talk to our test API server @@ -209,6 +200,10 @@ beforeAll(async () => { Parse.serverURL = 'http://localhost:' + port + '/1'; }); +beforeEach(() => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 10000; +}); + afterEach(function (done) { const afterLogOut = async () => { if (Object.keys(openConnections).length > 0) { @@ -225,6 +220,7 @@ afterEach(function (done) { done(); }; Parse.Cloud._removeAllHooks(); + Parse.CoreManager.getLiveQueryController().setDefaultLiveQueryClient(); defaults.protectedFields = { _User: { '*': ['email'] } }; databaseAdapter .getAllClasses() @@ -420,6 +416,7 @@ global.defaultConfiguration = defaultConfiguration; global.mockCustomAuthenticator = mockCustomAuthenticator; global.mockFacebookAuthenticator = mockFacebookAuthenticator; global.databaseAdapter = databaseAdapter; +global.databaseURI = databaseURI; global.jfail = function (err) { fail(JSON.stringify(err)); }; @@ -432,6 +429,29 @@ global.it_exclude_dbs = excluded => { } }; +let testExclusionList = []; +try { + // Fetch test exclusion list + testExclusionList = require('./testExclusionList.json'); + console.log(`Using test exclusion list with ${testExclusionList.length} entries`); +} catch(error) { + if(error.code !== 'MODULE_NOT_FOUND') { + throw error; + } +} + +// Disable test if its UUID is found in testExclusionList +global.it_id = (id, func) => { + if (testExclusionList.includes(id)) { + return xit; + } else { + if(func === undefined) + return it; + else + return func; + } +}; + global.it_only_db = db => { if ( process.env.PARSE_SERVER_TEST_DB === db || @@ -551,6 +571,16 @@ global.describe_only_db = db => { } }; +global.fdescribe_only_db = db => { + if (process.env.PARSE_SERVER_TEST_DB == db) { + return fdescribe; + } else if (!process.env.PARSE_SERVER_TEST_DB && db == 'mongo') { + return fdescribe; + } else { + return xdescribe; + } +}; + global.describe_only = validator => { if (validator()) { return describe; @@ -576,4 +606,4 @@ jasmine.restoreLibrary = function (library, name) { require(library)[name] = libraryCache[library][name]; }; -jasmine.timeout = t => new Promise(resolve => setTimeout(resolve, t)); +jasmine.timeout = (t = 100) => new Promise(resolve => setTimeout(resolve, t)); diff --git a/spec/index.spec.js b/spec/index.spec.js index 837656d1f2..66654aaec4 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -61,34 +61,19 @@ describe('server', () => { }); }); - it('fails if database is unreachable', done => { - reconfigureServer({ + it('fails if database is unreachable', async () => { + const server = new ParseServer.default({ + ...defaultConfiguration, databaseAdapter: new MongoStorageAdapter({ uri: 'mongodb://fake:fake@localhost:43605/drew3', mongoOptions: { serverSelectionTimeoutMS: 2000, }, }), - }).catch(() => { - const config = Config.get('test'); - config.schemaCache.clear(); - //Need to use rest api because saving via JS SDK results in fail() not getting called - request({ - method: 'POST', - url: 'http://localhost:8378/1/classes/NewClass', - headers: { - 'X-Parse-Application-Id': 'test', - 'X-Parse-REST-API-Key': 'rest', - }, - body: {}, - }).then(fail, response => { - expect(response.status).toEqual(500); - const body = response.data; - expect(body.code).toEqual(1); - expect(body.message).toEqual('Internal server error.'); - reconfigureServer().then(done, done); - }); }); + const error = await server.start().catch(e => e); + expect(`${error}`.includes('MongoServerSelectionError')).toBeTrue(); + await reconfigureServer(); }); describe('mail adapter', () => { @@ -295,91 +280,47 @@ describe('server', () => { }); }); - it('can create a parse-server v1', done => { + it('can create a parse-server v1', async () => { + await reconfigureServer({ appId: 'aTestApp' }); const parseServer = new ParseServer.default( Object.assign({}, defaultConfiguration, { appId: 'aTestApp', masterKey: 'aTestMasterKey', serverURL: 'http://localhost:12666/parse', - serverStartComplete: () => { - expect(Parse.applicationId).toEqual('aTestApp'); - const app = express(); - app.use('/parse', parseServer.app); - - const server = app.listen(12666); - const obj = new Parse.Object('AnObject'); - let objId; - obj - .save() - .then(obj => { - objId = obj.id; - const q = new Parse.Query('AnObject'); - return q.first(); - }) - .then(obj => { - expect(obj.id).toEqual(objId); - server.close(async () => { - await reconfigureServer(); - done(); - }); - }) - .catch(() => { - server.close(async () => { - await reconfigureServer(); - done(); - }); - }); - }, }) ); - }); - - it('can create a parse-server v2', done => { - let objId; - let server; + await parseServer.start(); + expect(Parse.applicationId).toEqual('aTestApp'); + const app = express(); + app.use('/parse', parseServer.app); + const server = app.listen(12666); + const obj = new Parse.Object('AnObject'); + await obj.save(); + const query = await new Parse.Query('AnObject').first(); + expect(obj.id).toEqual(query.id); + await new Promise(resolve => server.close(resolve)); + }); + + it('can create a parse-server v2', async () => { + await reconfigureServer({ appId: 'anOtherTestApp' }); const parseServer = ParseServer.ParseServer( Object.assign({}, defaultConfiguration, { appId: 'anOtherTestApp', masterKey: 'anOtherTestMasterKey', serverURL: 'http://localhost:12667/parse', - serverStartComplete: error => { - const promise = error ? Promise.reject(error) : Promise.resolve(); - promise - .then(() => { - expect(Parse.applicationId).toEqual('anOtherTestApp'); - const app = express(); - app.use('/parse', parseServer); - - server = app.listen(12667); - const obj = new Parse.Object('AnObject'); - return obj.save(); - }) - .then(obj => { - objId = obj.id; - const q = new Parse.Query('AnObject'); - return q.first(); - }) - .then(obj => { - expect(obj.id).toEqual(objId); - server.close(async () => { - await reconfigureServer(); - done(); - }); - }) - .catch(error => { - fail(JSON.stringify(error)); - if (server) { - server.close(async () => { - await reconfigureServer(); - done(); - }); - } else { - done(); - } - }); - }, }) ); + + expect(Parse.applicationId).toEqual('anOtherTestApp'); + await parseServer.start(); + const app = express(); + app.use('/parse', parseServer.app); + const server = app.listen(12667); + const obj = new Parse.Object('AnObject'); + await obj.save(); + const q = await new Parse.Query('AnObject').first(); + expect(obj.id).toEqual(q.id); + await new Promise(resolve => server.close(resolve)); }); it('has createLiveQueryServer', done => { @@ -426,6 +367,22 @@ describe('server', () => { }); }); + it('should throw when extendSessionOnUse is invalid', async () => { + await expectAsync( + reconfigureServer({ + extendSessionOnUse: 'yolo', + }) + ).toBeRejectedWith('extendSessionOnUse must be a boolean value'); + }); + + it('should throw when revokeSessionOnPasswordReset is invalid', async () => { + await expectAsync( + reconfigureServer({ + revokeSessionOnPasswordReset: 'yolo', + }) + ).toBeRejectedWith('revokeSessionOnPasswordReset must be a boolean value'); + }); + it('fails if the session length is not a number', done => { reconfigureServer({ sessionLength: 'test' }) .then(done.fail) @@ -495,7 +452,9 @@ describe('server', () => { it('fails if you provides invalid ip in masterKeyIps', done => { reconfigureServer({ masterKeyIps: ['invalidIp', '1.2.3.4'] }).catch(error => { - expect(error).toEqual('Invalid ip in masterKeyIps: invalidIp'); + expect(error).toEqual( + 'The Parse Server option "masterKeyIps" contains an invalid IP address "invalidIp".' + ); done(); }); }); @@ -506,6 +465,11 @@ describe('server', () => { }).then(done); }); + it('should set default masterKeyIps for IPv4 and IPv6 localhost', () => { + const definitions = require('../lib/Options/Definitions.js'); + expect(definitions.ParseServerOptions.masterKeyIps.default).toEqual(['127.0.0.1', '::1']); + }); + it('should load a middleware', done => { const obj = { middleware: function (req, res, next) { @@ -551,8 +515,95 @@ describe('server', () => { .catch(done.fail); }); + it('can call start', async () => { + await reconfigureServer({ appId: 'aTestApp' }); + const config = { + ...defaultConfiguration, + appId: 'aTestApp', + masterKey: 'aTestMasterKey', + serverURL: 'http://localhost:12701/parse', + }; + const parseServer = new ParseServer.ParseServer(config); + await parseServer.start(); + expect(Parse.applicationId).toEqual('aTestApp'); + expect(Parse.serverURL).toEqual('http://localhost:12701/parse'); + const app = express(); + app.use('/parse', parseServer.app); + const server = app.listen(12701); + const testObject = new Parse.Object('TestObject'); + await expectAsync(testObject.save()).toBeResolved(); + await new Promise(resolve => server.close(resolve)); + }); + + it('start is required to mount', async () => { + await reconfigureServer({ appId: 'aTestApp' }); + const config = { + ...defaultConfiguration, + appId: 'aTestApp', + masterKey: 'aTestMasterKey', + serverURL: 'http://localhost:12701/parse', + }; + const parseServer = new ParseServer.ParseServer(config); + expect(Parse.applicationId).toEqual('aTestApp'); + expect(Parse.serverURL).toEqual('http://localhost:12701/parse'); + const app = express(); + app.use('/parse', parseServer.app); + const server = app.listen(12701); + const response = await request({ + headers: { + 'X-Parse-Application-Id': 'aTestApp', + }, + method: 'POST', + url: 'http://localhost:12701/parse/classes/TestObject', + }).catch(e => new Parse.Error(e.data.code, e.data.error)); + expect(response).toEqual( + new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Invalid server state: initialized') + ); + const health = await request({ + url: 'http://localhost:12701/parse/health', + }).catch(e => e); + spyOn(console, 'warn').and.callFake(() => {}); + const verify = await ParseServer.default.verifyServerUrl(); + expect(verify).not.toBeTrue(); + expect(console.warn).toHaveBeenCalledWith( + `\nWARNING, Unable to connect to 'http://localhost:12701/parse'. Cloud code and push notifications may be unavailable!\n` + ); + expect(health.data.status).toBe('initialized'); + expect(health.status).toBe(503); + await new Promise(resolve => server.close(resolve)); + }); + + it('can get starting state', async () => { + await reconfigureServer({ appId: 'test2' }); + const parseServer = new ParseServer.ParseServer({ + ...defaultConfiguration, + appId: 'test2', + masterKey: 'abc', + serverURL: 'http://localhost:12668/parse', + async cloud() { + await new Promise(resolve => setTimeout(resolve, 2000)); + }, + }); + const express = require('express'); + const app = express(); + app.use('/parse', parseServer.app); + const server = app.listen(12668); + const startingPromise = parseServer.start(); + const health = await request({ + url: 'http://localhost:12668/parse/health', + }).catch(e => e); + expect(health.data.status).toBe('starting'); + expect(health.status).toBe(503); + expect(health.headers['retry-after']).toBe('1'); + const response = await ParseServer.default.verifyServerUrl(); + expect(response).toBeTrue(); + await startingPromise; + await new Promise(resolve => server.close(resolve)); + }); + it('should not fail when Google signin is introduced without the optional clientId', done => { const jwt = require('jsonwebtoken'); + const authUtils = require('../lib/Adapters/Auth/utils'); reconfigureServer({ auth: { google: {} }, @@ -565,7 +616,7 @@ describe('server', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const user = new Parse.User(); user diff --git a/spec/rest.spec.js b/spec/rest.spec.js index db3082ec74..dc4e78ad0a 100644 --- a/spec/rest.spec.js +++ b/spec/rest.spec.js @@ -136,6 +136,117 @@ describe('rest create', () => { }); }); + describe('with maintenance key', () => { + let req; + + async function getObject(id) { + const res = await request({ + headers: { + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }, + method: 'GET', + url: `http://localhost:8378/1/classes/TestObject/${id}`, + }); + + return res.data; + } + + beforeEach(() => { + req = { + headers: { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + 'X-Parse-Maintenance-Key': 'testing', + }, + method: 'POST', + url: 'http://localhost:8378/1/classes/TestObject', + }; + }); + + it('allows createdAt', async () => { + const createdAt = { __type: 'Date', iso: '2019-01-01T00:00:00.000Z' }; + req.body = { createdAt }; + + const res = await request(req); + expect(res.data.createdAt).toEqual(createdAt.iso); + }); + + it('allows createdAt and updatedAt', async () => { + const createdAt = { __type: 'Date', iso: '2019-01-01T00:00:00.000Z' }; + const updatedAt = { __type: 'Date', iso: '2019-02-01T00:00:00.000Z' }; + req.body = { createdAt, updatedAt }; + + const res = await request(req); + + const obj = await getObject(res.data.objectId); + expect(obj.createdAt).toEqual(createdAt.iso); + expect(obj.updatedAt).toEqual(updatedAt.iso); + }); + + it('allows createdAt, updatedAt, and additional field', async () => { + const createdAt = { __type: 'Date', iso: '2019-01-01T00:00:00.000Z' }; + const updatedAt = { __type: 'Date', iso: '2019-02-01T00:00:00.000Z' }; + req.body = { createdAt, updatedAt, testing: 123 }; + + const res = await request(req); + + const obj = await getObject(res.data.objectId); + expect(obj.createdAt).toEqual(createdAt.iso); + expect(obj.updatedAt).toEqual(updatedAt.iso); + expect(obj.testing).toEqual(123); + }); + + it('cannot set updatedAt dated before createdAt', async () => { + const createdAt = { __type: 'Date', iso: '2019-01-01T00:00:00.000Z' }; + const updatedAt = { __type: 'Date', iso: '2018-12-01T00:00:00.000Z' }; + req.body = { createdAt, updatedAt }; + + try { + await request(req); + fail(); + } catch (err) { + expect(err.data.code).toEqual(Parse.Error.VALIDATION_ERROR); + } + }); + + it('cannot set updatedAt without createdAt', async () => { + const updatedAt = { __type: 'Date', iso: '2018-12-01T00:00:00.000Z' }; + req.body = { updatedAt }; + + const res = await request(req); + + const obj = await getObject(res.data.objectId); + expect(obj.updatedAt).not.toEqual(updatedAt.iso); + }); + + it('handles bad types for createdAt and updatedAt', async () => { + const createdAt = 12345; + const updatedAt = true; + req.body = { createdAt, updatedAt }; + + try { + await request(req); + fail(); + } catch (err) { + expect(err.data.code).toEqual(Parse.Error.INCORRECT_TYPE); + } + }); + + it('cannot set createdAt or updatedAt without maintenance key', async () => { + const createdAt = { __type: 'Date', iso: '2019-01-01T00:00:00.000Z' }; + const updatedAt = { __type: 'Date', iso: '2019-02-01T00:00:00.000Z' }; + req.body = { createdAt, updatedAt }; + delete req.headers['X-Parse-Maintenance-Key']; + + const res = await request(req); + + expect(res.data.createdAt).not.toEqual(createdAt.iso); + expect(res.data.updatedAt).not.toEqual(updatedAt.iso); + }); + }); + it('handles array, object, date', done => { const now = new Date(); const obj = { @@ -660,6 +771,38 @@ describe('rest create', () => { }); }); + it('cannot get object in volatileClasses if not masterKey through pointer', async () => { + const masterKeyOnlyClassObject = new Parse.Object('_PushStatus'); + await masterKeyOnlyClassObject.save(null, { useMasterKey: true }); + const obj2 = new Parse.Object('TestObject'); + // Anyone is can basically create a pointer to any object + // or some developers can use master key in some hook to link + // private objects to standard objects + obj2.set('pointer', masterKeyOnlyClassObject); + await obj2.save(); + const query = new Parse.Query('TestObject'); + query.include('pointer'); + await expectAsync(query.get(obj2.id)).toBeRejectedWithError( + "Clients aren't allowed to perform the get operation on the _PushStatus collection." + ); + }); + + it('cannot get object in _GlobalConfig if not masterKey through pointer', async () => { + await Parse.Config.save({ privateData: 'secret' }, { privateData: true }); + const obj2 = new Parse.Object('TestObject'); + obj2.set('globalConfigPointer', { + __type: 'Pointer', + className: '_GlobalConfig', + objectId: 1, + }); + await obj2.save(); + const query = new Parse.Query('TestObject'); + query.include('globalConfigPointer'); + await expectAsync(query.get(obj2.id)).toBeRejectedWithError( + "Clients aren't allowed to perform the get operation on the _GlobalConfig collection." + ); + }); + it('locks down session', done => { let currentUser; Parse.User.signUp('foo', 'bar') @@ -859,6 +1002,15 @@ describe('read-only masterKey', () => { await reconfigureServer(); }); + it('should throw when masterKey and maintenanceKey are the same', async () => { + await expectAsync( + reconfigureServer({ + masterKey: 'yolo', + maintenanceKey: 'yolo', + }) + ).toBeRejectedWith(new Error('masterKey and maintenanceKey should be different')); + }); + it('should throw when trying to create RestWrite', () => { const config = Config.get('test'); expect(() => { diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index 2123961f65..60112ae82c 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -6,14 +6,20 @@ const ParseServer = require('../../lib/index').ParseServer; const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDatabase'; -ParseServer.start({ - appId: 'test', - masterKey: 'test', - databaseAdapter: new MongoStorageAdapter({ - uri: databaseURI, - mongoOptions: { - serverSelectionTimeoutMS: 2000, - }, - }), - filesAdapter: new GridFSBucketAdapter(databaseURI), -}); +(async () => { + try { + await ParseServer.startApp({ + appId: 'test', + masterKey: 'test', + databaseAdapter: new MongoStorageAdapter({ + uri: databaseURI, + mongoOptions: { + serverSelectionTimeoutMS: 2000, + }, + }), + filesAdapter: new GridFSBucketAdapter(databaseURI), + }); + } catch (e) { + process.exit(1); + } +})(); diff --git a/spec/vulnerabilities.spec.js b/spec/vulnerabilities.spec.js index 5c83493c94..c0f519e78d 100644 --- a/spec/vulnerabilities.spec.js +++ b/spec/vulnerabilities.spec.js @@ -138,6 +138,71 @@ describe('Vulnerabilities', () => { ); }); + it('denies creating global config with polluted data', async () => { + const headers = { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-Master-Key': 'test', + }; + const params = { + method: 'PUT', + url: 'http://localhost:8378/1/config', + json: true, + body: { + params: { + welcomeMesssage: 'Welcome to Parse', + foo: { _bsontype: 'Code', code: 'shell' }, + }, + }, + headers, + }; + const response = await request(params).catch(e => e); + expect(response.status).toBe(400); + const text = JSON.parse(response.text); + expect(text.code).toBe(Parse.Error.INVALID_KEY_NAME); + expect(text.error).toBe( + 'Prohibited keyword in request data: {"key":"_bsontype","value":"Code"}.' + ); + }); + + it('denies direct database write wih prohibited keys', async () => { + const Config = require('../lib/Config'); + const config = Config.get(Parse.applicationId); + const user = { + objectId: '1234567890', + username: 'hello', + password: 'pass', + _session_token: 'abc', + foo: { _bsontype: 'Code', code: 'shell' }, + }; + await expectAsync(config.database.create('_User', user)).toBeRejectedWith( + new Parse.Error( + Parse.Error.INVALID_KEY_NAME, + 'Prohibited keyword in request data: {"key":"_bsontype","value":"Code"}.' + ) + ); + }); + + it('denies direct database update wih prohibited keys', async () => { + const Config = require('../lib/Config'); + const config = Config.get(Parse.applicationId); + const user = { + objectId: '1234567890', + username: 'hello', + password: 'pass', + _session_token: 'abc', + foo: { _bsontype: 'Code', code: 'shell' }, + }; + await expectAsync( + config.database.update('_User', { _id: user.objectId }, user) + ).toBeRejectedWith( + new Parse.Error( + Parse.Error.INVALID_KEY_NAME, + 'Prohibited keyword in request data: {"key":"_bsontype","value":"Code"}.' + ) + ); + }); + it('denies creating a hook with polluted data', async () => { const express = require('express'); const bodyParser = require('body-parser'); @@ -170,32 +235,6 @@ describe('Vulnerabilities', () => { await new Promise(resolve => server.close(resolve)); }); - it('allows BSON type code data in write request with custom denylist', async () => { - await reconfigureServer({ - requestKeywordDenylist: [], - }); - const headers = { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': 'test', - 'X-Parse-REST-API-Key': 'rest', - }; - const params = { - headers: headers, - method: 'POST', - url: 'http://localhost:8378/1/classes/RCE', - body: JSON.stringify({ - obj: { - _bsontype: 'Code', - code: 'delete Object.prototype.evalFunctions', - }, - }), - }; - const response = await request(params).catch(e => e); - expect(response.status).toBe(201); - const text = JSON.parse(response.text); - expect(text.objectId).toBeDefined(); - }); - it('denies write request with custom denylist of key/value', async () => { await reconfigureServer({ requestKeywordDenylist: [{ key: 'a[K]ey', value: 'aValue[123]*' }], @@ -394,3 +433,28 @@ describe('Vulnerabilities', () => { }); }); }); + +describe('Postgres regex sanitizater', () => { + it('sanitizes the regex correctly to prevent Injection', async () => { + const user = new Parse.User(); + user.set('username', 'username'); + user.set('password', 'password'); + user.set('email', 'email@example.com'); + await user.signUp(); + + const response = await request({ + method: 'GET', + url: + "http://localhost:8378/1/classes/_User?where[username][$regex]=A'B'%3BSELECT+PG_SLEEP(3)%3B--", + headers: { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'test', + 'X-Parse-REST-API-Key': 'rest', + }, + }); + + expect(response.status).toBe(200); + expect(response.data.results).toEqual(jasmine.any(Array)); + expect(response.data.results.length).toBe(0); + }); +}); diff --git a/src/Adapters/Analytics/AnalyticsAdapter.js b/src/Adapters/Analytics/AnalyticsAdapter.js index 3fd50242d9..e3cced14f5 100644 --- a/src/Adapters/Analytics/AnalyticsAdapter.js +++ b/src/Adapters/Analytics/AnalyticsAdapter.js @@ -1,9 +1,7 @@ /*eslint no-unused-vars: "off"*/ -/** - * @module Adapters - */ /** * @interface AnalyticsAdapter + * @module Adapters */ export class AnalyticsAdapter { /** diff --git a/src/Adapters/Auth/AuthAdapter.js b/src/Adapters/Auth/AuthAdapter.js index 9af6d5e449..e739df3f54 100644 --- a/src/Adapters/Auth/AuthAdapter.js +++ b/src/Adapters/Auth/AuthAdapter.js @@ -1,22 +1,118 @@ /*eslint no-unused-vars: "off"*/ + +/** + * @interface ParseAuthResponse + * @property {Boolean} [doNotSave] If true, Parse Server will not save provided authData. + * @property {Object} [response] If set, Parse Server will send the provided response to the client under authDataResponse + * @property {Object} [save] If set, Parse Server will save the object provided into this key, instead of client provided authData + */ + +/** + * AuthPolicy + * default: can be combined with ONE additional auth provider if additional configured on user + * additional: could be only used with a default policy auth provider + * solo: Will ignore ALL additional providers if additional configured on user + * @typedef {"default" | "additional" | "solo"} AuthPolicy + */ + export class AuthAdapter { - /* - @param appIds: the specified app ids in the configuration - @param authData: the client provided authData - @param options: additional options - @returns a promise that resolves if the applicationId is valid + constructor() { + /** + * Usage policy + * @type {AuthPolicy} + */ + if (!this.policy) { + this.policy = 'default'; + } + } + /** + * @param appIds The specified app IDs in the configuration + * @param {Object} authData The client provided authData + * @param {Object} options additional adapter options + * @param {Parse.Cloud.TriggerRequest} request + * @returns {(Promise|void|undefined)} resolves or returns if the applicationId is valid + */ + validateAppId(appIds, authData, options, request) { + return Promise.resolve({}); + } + + /** + * Legacy usage, if provided it will be triggered when authData related to this provider is touched (signup/update/login) + * otherwise you should implement validateSetup, validateLogin and validateUpdate + * @param {Object} authData The client provided authData + * @param {Parse.Cloud.TriggerRequest} request + * @param {Object} options additional adapter options + * @returns {Promise} */ - validateAppId(appIds, authData, options) { + validateAuthData(authData, request, options) { return Promise.resolve({}); } - /* - @param authData: the client provided authData - @param options: additional options + /** + * Triggered when user provide for the first time this auth provider + * could be a register or the user adding a new auth service + * @param {Object} authData The client provided authData + * @param {Parse.Cloud.TriggerRequest} request + * @param {Object} options additional adapter options + * @returns {Promise} */ - validateAuthData(authData, options) { + validateSetUp(authData, req, options) { return Promise.resolve({}); } + + /** + * Triggered when user provide authData related to this provider + * The user is not logged in and has already set this provider before + * @param {Object} authData The client provided authData + * @param {Parse.Cloud.TriggerRequest} request + * @param {Object} options additional adapter options + * @returns {Promise} + */ + validateLogin(authData, req, options) { + return Promise.resolve({}); + } + + /** + * Triggered when user provide authData related to this provider + * the user is logged in and has already set this provider before + * @param {Object} authData The client provided authData + * @param {Object} options additional adapter options + * @param {Parse.Cloud.TriggerRequest} request + * @returns {Promise} + */ + validateUpdate(authData, req, options) { + return Promise.resolve({}); + } + + /** + * Triggered in pre authentication process if needed (like webauthn, SMS OTP) + * @param {Object} challengeData Data provided by the client + * @param {(Object|undefined)} authData Auth data provided by the client, can be used for validation + * @param {Object} options additional adapter options + * @param {Parse.Cloud.TriggerRequest} request + * @returns {Promise} A promise that resolves, resolved value will be added to challenge response under challenge key + */ + challenge(challengeData, authData, options, request) { + return Promise.resolve({}); + } + + /** + * Triggered when auth data is fetched + * @param {Object} authData authData + * @param {Object} options additional adapter options + * @returns {Promise} Any overrides required to authData + */ + afterFind(authData, options) { + return Promise.resolve({}); + } + + /** + * Triggered when the adapter is first attached to Parse Server + * @param {Object} options Adapter Options + */ + validateOptions(options) { + /* */ + } } export default AuthAdapter; diff --git a/src/Adapters/Auth/apple.js b/src/Adapters/Auth/apple.js index 18989a4529..4fd1153b75 100644 --- a/src/Adapters/Auth/apple.js +++ b/src/Adapters/Auth/apple.js @@ -3,8 +3,8 @@ const Parse = require('parse/node').Parse; const jwksClient = require('jwks-rsa'); -const util = require('util'); const jwt = require('jsonwebtoken'); +const authUtils = require('./utils'); const TOKEN_ISSUER = 'https://appleid.apple.com'; @@ -16,11 +16,9 @@ const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { cacheMaxAge, }); - const asyncGetSigningKeyFunction = util.promisify(client.getSigningKey); - let key; try { - key = await asyncGetSigningKeyFunction(keyId); + key = await authUtils.getSigningKey(client, keyId); } catch (error) { throw new Parse.Error( Parse.Error.OBJECT_NOT_FOUND, @@ -30,21 +28,12 @@ const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { return key; }; -const getHeaderFromToken = token => { - const decodedToken = jwt.decode(token, { complete: true }); - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -}; - const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => { if (!token) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); } - const { kid: keyId, alg: algorithm } = getHeaderFromToken(token); + const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token); const ONE_HOUR_IN_MS = 3600000; let jwtClaims; diff --git a/src/Adapters/Auth/facebook.js b/src/Adapters/Auth/facebook.js index e937bb1bb5..896fad0ff4 100644 --- a/src/Adapters/Auth/facebook.js +++ b/src/Adapters/Auth/facebook.js @@ -2,9 +2,9 @@ const Parse = require('parse/node').Parse; const crypto = require('crypto'); const jwksClient = require('jwks-rsa'); -const util = require('util'); const jwt = require('jsonwebtoken'); const httpsRequest = require('./httpsRequest'); +const authUtils = require('./utils'); const TOKEN_ISSUER = 'https://facebook.com'; @@ -59,11 +59,9 @@ const getFacebookKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { cacheMaxAge, }); - const asyncGetSigningKeyFunction = util.promisify(client.getSigningKey); - let key; try { - key = await asyncGetSigningKeyFunction(keyId); + key = await authUtils.getSigningKey(client, keyId); } catch (error) { throw new Parse.Error( Parse.Error.OBJECT_NOT_FOUND, @@ -73,21 +71,12 @@ const getFacebookKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { return key; }; -const getHeaderFromToken = token => { - const decodedToken = jwt.decode(token, { complete: true }); - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'provided token does not decode as JWT'); - } - - return decodedToken.header; -}; - const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => { if (!token) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'id token is invalid for this user.'); } - const { kid: keyId, alg: algorithm } = getHeaderFromToken(token); + const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token); const ONE_HOUR_IN_MS = 3600000; let jwtClaims; diff --git a/src/Adapters/Auth/google.js b/src/Adapters/Auth/google.js index 8691cf9cae..755eb3c673 100644 --- a/src/Adapters/Auth/google.js +++ b/src/Adapters/Auth/google.js @@ -5,6 +5,7 @@ var Parse = require('parse/node').Parse; const https = require('https'); const jwt = require('jsonwebtoken'); +const authUtils = require('./utils'); const TOKEN_ISSUER = 'accounts.google.com'; const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com'; @@ -51,22 +52,12 @@ function getGoogleKeyByKeyId(keyId) { }); } -function getHeaderFromToken(token) { - const decodedToken = jwt.decode(token, { complete: true }); - - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -} - async function verifyIdToken({ id_token: token, id }, { clientId }) { if (!token) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); } - const { kid: keyId, alg: algorithm } = getHeaderFromToken(token); + const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token); let jwtClaims; const googleKey = await getGoogleKeyByKeyId(keyId); diff --git a/src/Adapters/Auth/index.js b/src/Adapters/Auth/index.js index 00637d1131..da65b24ba5 100755 --- a/src/Adapters/Auth/index.js +++ b/src/Adapters/Auth/index.js @@ -1,4 +1,6 @@ import loadAdapter from '../AdapterLoader'; +import Parse from 'parse/node'; +import AuthAdapter from './AuthAdapter'; const apple = require('./apple'); const gcenter = require('./gcenter'); @@ -7,6 +9,7 @@ const facebook = require('./facebook'); const instagram = require('./instagram'); const linkedin = require('./linkedin'); const meetup = require('./meetup'); +import mfa from './mfa'; const google = require('./google'); const github = require('./github'); const twitter = require('./twitter'); @@ -42,6 +45,7 @@ const providers = { instagram, linkedin, meetup, + mfa, google, github, twitter, @@ -61,19 +65,87 @@ const providers = { ldap, }; -function authDataValidator(adapter, appIds, options) { - return function (authData) { - return adapter.validateAuthData(authData, options).then(() => { - if (appIds) { - return adapter.validateAppId(appIds, authData, options); +// Indexed auth policies +const authAdapterPolicies = { + default: true, + solo: true, + additional: true, +}; + +function authDataValidator(provider, adapter, appIds, options) { + return async function (authData, req, user, requestObject) { + if (appIds && typeof adapter.validateAppId === 'function') { + await Promise.resolve(adapter.validateAppId(appIds, authData, options, requestObject)); + } + if ( + adapter.policy && + !authAdapterPolicies[adapter.policy] && + typeof adapter.policy !== 'function' + ) { + throw new Parse.Error( + Parse.Error.OTHER_CAUSE, + 'AuthAdapter policy is not configured correctly. The value must be either "solo", "additional", "default" or undefined (will be handled as "default")' + ); + } + if (typeof adapter.validateAuthData === 'function') { + return adapter.validateAuthData(authData, options, requestObject); + } + if ( + typeof adapter.validateSetUp !== 'function' || + typeof adapter.validateLogin !== 'function' || + typeof adapter.validateUpdate !== 'function' + ) { + throw new Parse.Error( + Parse.Error.OTHER_CAUSE, + 'Adapter is not configured. Implement either validateAuthData or all of the following: validateSetUp, validateLogin and validateUpdate' + ); + } + // When masterKey is detected, we should trigger a logged in user + const isLoggedIn = + (req.auth.user && user && req.auth.user.id === user.id) || (user && req.auth.isMaster); + let hasAuthDataConfigured = false; + + if (user && user.get('authData') && user.get('authData')[provider]) { + hasAuthDataConfigured = true; + } + + if (isLoggedIn) { + // User is updating their authData + if (hasAuthDataConfigured) { + return { + method: 'validateUpdate', + validator: () => adapter.validateUpdate(authData, options, requestObject), + }; } - return Promise.resolve(); - }); + // Set up if the user does not have the provider configured + return { + method: 'validateSetUp', + validator: () => adapter.validateSetUp(authData, options, requestObject), + }; + } + + // Not logged in and authData is configured on the user + if (hasAuthDataConfigured) { + return { + method: 'validateLogin', + validator: () => adapter.validateLogin(authData, options, requestObject), + }; + } + + // User not logged in and the provider is not set up, for example when a new user + // signs up or an existing user uses a new auth provider + return { + method: 'validateSetUp', + validator: () => adapter.validateSetUp(authData, options, requestObject), + }; }; } function loadAuthAdapter(provider, authOptions) { + // providers are auth providers implemented by default let defaultAdapter = providers[provider]; + // authOptions can contain complete custom auth adapters or + // a default auth adapter like Facebook const providerOptions = authOptions[provider]; if ( providerOptions && @@ -83,31 +155,50 @@ function loadAuthAdapter(provider, authOptions) { defaultAdapter = oauth2; } + // Default provider not found and a custom auth provider was not provided if (!defaultAdapter && !providerOptions) { return; } - const adapter = Object.assign({}, defaultAdapter); + const adapter = + defaultAdapter instanceof AuthAdapter ? defaultAdapter : Object.assign({}, defaultAdapter); + const keys = [ + 'validateAuthData', + 'validateAppId', + 'validateSetUp', + 'validateLogin', + 'validateUpdate', + 'challenge', + 'validateOptions', + 'policy', + 'afterFind', + ]; + const defaultAuthAdapter = new AuthAdapter(); + keys.forEach(key => { + const existing = adapter?.[key]; + if ( + existing && + typeof existing === 'function' && + existing.toString() === defaultAuthAdapter[key].toString() + ) { + adapter[key] = null; + } + }); const appIds = providerOptions ? providerOptions.appIds : undefined; // Try the configuration methods if (providerOptions) { const optionalAdapter = loadAdapter(providerOptions, undefined, providerOptions); if (optionalAdapter) { - ['validateAuthData', 'validateAppId'].forEach(key => { + keys.forEach(key => { if (optionalAdapter[key]) { adapter[key] = optionalAdapter[key]; } }); } } - - // TODO: create a new module from validateAdapter() in - // src/Controllers/AdaptableController.js so we can use it here for adapter - // validation based on the src/Adapters/Auth/AuthAdapter.js expected class - // signature. - if (!adapter.validateAuthData || !adapter.validateAppId) { - return; + if (adapter.validateOptions) { + adapter.validateOptions(providerOptions); } return { adapter, appIds, providerOptions }; @@ -121,17 +212,51 @@ module.exports = function (authOptions = {}, enableAnonymousUsers = true) { // To handle the test cases on configuration const getValidatorForProvider = function (provider) { if (provider === 'anonymous' && !_enableAnonymousUsers) { - return; + return { validator: undefined }; } + const authAdapter = loadAuthAdapter(provider, authOptions); + if (!authAdapter) return; + const { adapter, appIds, providerOptions } = authAdapter; + return { validator: authDataValidator(provider, adapter, appIds, providerOptions), adapter }; + }; - const { adapter, appIds, providerOptions } = loadAuthAdapter(provider, authOptions); - - return authDataValidator(adapter, appIds, providerOptions); + const runAfterFind = async (req, authData) => { + if (!authData) { + return; + } + const adapters = Object.keys(authData); + await Promise.all( + adapters.map(async provider => { + const authAdapter = getValidatorForProvider(provider); + if (!authAdapter) { + return; + } + const { adapter, providerOptions } = authAdapter; + const afterFind = adapter.afterFind; + if (afterFind && typeof afterFind === 'function') { + const requestObject = { + ip: req.config.ip, + user: req.auth.user, + master: req.auth.isMaster, + }; + const result = afterFind.call( + adapter, + requestObject, + authData[provider], + providerOptions + ); + if (result) { + authData[provider] = result; + } + } + }) + ); }; return Object.freeze({ getValidatorForProvider, setEnableAnonymousUsers, + runAfterFind, }); }; diff --git a/src/Adapters/Auth/ldap.js b/src/Adapters/Auth/ldap.js index 7cea9e3f2b..8ea735698f 100644 --- a/src/Adapters/Auth/ldap.js +++ b/src/Adapters/Auth/ldap.js @@ -78,7 +78,7 @@ function searchForGroup(client, options, id, resolve, reject) { return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); } res.on('searchEntry', entry => { - if (entry.object.cn === options.groupCn) { + if (entry.pojo.attributes.find(obj => obj.type === 'cn').values.includes(options.groupCn)) { found = true; client.unbind(); client.destroy(); diff --git a/src/Adapters/Auth/mfa.js b/src/Adapters/Auth/mfa.js new file mode 100644 index 0000000000..a88eda99e7 --- /dev/null +++ b/src/Adapters/Auth/mfa.js @@ -0,0 +1,213 @@ +import { TOTP, Secret } from 'otpauth'; +import { randomString } from '../../cryptoUtils'; +import AuthAdapter from './AuthAdapter'; +class MFAAdapter extends AuthAdapter { + validateOptions(opts) { + const validOptions = opts.options; + if (!Array.isArray(validOptions)) { + throw 'mfa.options must be an array'; + } + this.sms = validOptions.includes('SMS'); + this.totp = validOptions.includes('TOTP'); + if (!this.sms && !this.totp) { + throw 'mfa.options must include SMS or TOTP'; + } + const digits = opts.digits || 6; + const period = opts.period || 30; + if (typeof digits !== 'number') { + throw 'mfa.digits must be a number'; + } + if (typeof period !== 'number') { + throw 'mfa.period must be a number'; + } + if (digits < 4 || digits > 10) { + throw 'mfa.digits must be between 4 and 10'; + } + if (period < 10) { + throw 'mfa.period must be greater than 10'; + } + const sendSMS = opts.sendSMS; + if (this.sms && typeof sendSMS !== 'function') { + throw 'mfa.sendSMS callback must be defined when using SMS OTPs'; + } + this.smsCallback = sendSMS; + this.digits = digits; + this.period = period; + this.algorithm = opts.algorithm || 'SHA1'; + } + validateSetUp(mfaData) { + if (mfaData.mobile && this.sms) { + return this.setupMobileOTP(mfaData.mobile); + } + if (this.totp) { + return this.setupTOTP(mfaData); + } + throw 'Invalid MFA data'; + } + async validateLogin(loginData, _, req) { + const saveResponse = { + doNotSave: true, + }; + const token = loginData.token; + const auth = req.original.get('authData') || {}; + const { secret, recovery, mobile, token: saved, expiry } = auth.mfa || {}; + if (this.sms && mobile) { + if (token === 'request') { + const { token: sendToken, expiry } = await this.sendSMS(mobile); + auth.mfa.token = sendToken; + auth.mfa.expiry = expiry; + req.object.set('authData', auth); + await req.object.save(null, { useMasterKey: true }); + throw 'Please enter the token'; + } + if (!saved || token !== saved) { + throw 'Invalid MFA token 1'; + } + if (new Date() > expiry) { + throw 'Invalid MFA token 2'; + } + delete auth.mfa.token; + delete auth.mfa.expiry; + return { + save: auth.mfa, + }; + } + if (this.totp) { + if (typeof token !== 'string') { + throw 'Invalid MFA token'; + } + if (!secret) { + return saveResponse; + } + if (recovery[0] === token || recovery[1] === token) { + return saveResponse; + } + const totp = new TOTP({ + algorithm: this.algorithm, + digits: this.digits, + period: this.period, + secret: Secret.fromBase32(secret), + }); + const valid = totp.validate({ + token, + }); + if (valid === null) { + throw 'Invalid MFA token'; + } + } + return saveResponse; + } + async validateUpdate(authData, _, req) { + if (req.master) { + return; + } + if (authData.mobile && this.sms) { + if (!authData.token) { + throw 'MFA is already set up on this account'; + } + return this.confirmSMSOTP(authData, req.original.get('authData')?.mfa || {}); + } + if (this.totp) { + await this.validateLogin({ token: authData.old }, null, req); + return this.validateSetUp(authData); + } + throw 'Invalid MFA data'; + } + afterFind(req, authData) { + if (req.master) { + return; + } + if (this.totp && authData.secret) { + return { + status: 'enabled', + }; + } + if (this.sms && authData.mobile) { + return { + status: 'enabled', + }; + } + return { + status: 'disabled', + }; + } + + policy(req, auth) { + if (this.sms && auth?.pending && Object.keys(auth).length === 1) { + return 'default'; + } + return 'additional'; + } + + async setupMobileOTP(mobile) { + const { token, expiry } = await this.sendSMS(mobile); + return { + save: { + pending: { + [mobile]: { + token, + expiry, + }, + }, + }, + }; + } + + async sendSMS(mobile) { + if (!/^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]*$/g.test(mobile)) { + throw 'Invalid mobile number.'; + } + let token = ''; + while (token.length < this.digits) { + token += randomString(10).replace(/\D/g, ''); + } + token = token.substring(0, this.digits); + await Promise.resolve(this.smsCallback(token, mobile)); + const expiry = new Date(new Date().getTime() + this.period * 1000); + return { token, expiry }; + } + + async confirmSMSOTP(inputData, authData) { + const { mobile, token } = inputData; + if (!authData.pending?.[mobile]) { + throw 'This number is not pending'; + } + const pendingData = authData.pending[mobile]; + if (token !== pendingData.token) { + throw 'Invalid MFA token'; + } + if (new Date() > pendingData.expiry) { + throw 'Invalid MFA token'; + } + delete authData.pending[mobile]; + authData.mobile = mobile; + return { + save: authData, + }; + } + + setupTOTP(mfaData) { + const { secret, token } = mfaData; + if (!secret || !token || secret.length < 20) { + throw 'Invalid MFA data'; + } + const totp = new TOTP({ + algorithm: this.algorithm, + digits: this.digits, + period: this.period, + secret: Secret.fromBase32(secret), + }); + const valid = totp.validate({ + token, + }); + if (valid === null) { + throw 'Invalid MFA token'; + } + const recovery = [randomString(30), randomString(30)]; + return { + response: { recovery: recovery.join(', ') }, + save: { secret, recovery }, + }; + } +} +export default new MFAAdapter(); diff --git a/src/Adapters/Auth/utils.js b/src/Adapters/Auth/utils.js new file mode 100644 index 0000000000..0d4d7cd8a2 --- /dev/null +++ b/src/Adapters/Auth/utils.js @@ -0,0 +1,24 @@ +const jwt = require('jsonwebtoken'); +const util = require('util'); +const Parse = require('parse/node').Parse; +const getHeaderFromToken = token => { + const decodedToken = jwt.decode(token, { complete: true }); + if (!decodedToken) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); + } + + return decodedToken.header; +}; + +/** + * Returns the signing key from a JWKS client. + * @param {Object} client The JWKS client. + * @param {String} key The kid. + */ +async function getSigningKey(client, key) { + return util.promisify(client.getSigningKey)(key); +} +module.exports = { + getHeaderFromToken, + getSigningKey, +}; diff --git a/src/Adapters/Cache/CacheAdapter.js b/src/Adapters/Cache/CacheAdapter.js index 224d0c006e..7632797e55 100644 --- a/src/Adapters/Cache/CacheAdapter.js +++ b/src/Adapters/Cache/CacheAdapter.js @@ -1,9 +1,7 @@ /*eslint no-unused-vars: "off"*/ /** - * @module Adapters - */ -/** - * @interface CacheAdapter + * @interface + * @memberof module:Adapters */ export class CacheAdapter { /** diff --git a/src/Adapters/Cache/LRUCache.js b/src/Adapters/Cache/LRUCache.js index a07d0347eb..129a006376 100644 --- a/src/Adapters/Cache/LRUCache.js +++ b/src/Adapters/Cache/LRUCache.js @@ -1,4 +1,4 @@ -import LRU from 'lru-cache'; +import { LRUCache as LRU } from 'lru-cache'; import defaults from '../../defaults'; export class LRUCache { @@ -18,11 +18,11 @@ export class LRUCache { } del(key) { - this.cache.del(key); + this.cache.delete(key); } clear() { - this.cache.reset(); + this.cache.clear(); } } diff --git a/src/Adapters/Cache/RedisCacheAdapter.js b/src/Adapters/Cache/RedisCacheAdapter.js index 79dd2dc85a..a0345a1101 100644 --- a/src/Adapters/Cache/RedisCacheAdapter.js +++ b/src/Adapters/Cache/RedisCacheAdapter.js @@ -1,4 +1,4 @@ -import redis from 'redis'; +import { createClient } from 'redis'; import logger from '../../logger'; import { KeyPromiseQueue } from '../../KeyPromiseQueue'; @@ -15,114 +15,80 @@ const isValidTTL = ttl => typeof ttl === 'number' && ttl > 0; export class RedisCacheAdapter { constructor(redisCtx, ttl = DEFAULT_REDIS_TTL) { this.ttl = isValidTTL(ttl) ? ttl : DEFAULT_REDIS_TTL; - this.client = redis.createClient(redisCtx); + this.client = createClient(redisCtx); this.queue = new KeyPromiseQueue(); + this.client.on('error', err => { logger.error('RedisCacheAdapter client error', { error: err }) }); + this.client.on('connect', () => {}); + this.client.on('reconnecting', () => {}); + this.client.on('ready', () => {}); } - handleShutdown() { + async connect() { + if (this.client.isOpen) { + return; + } + return this.client.connect(); + } + + async handleShutdown() { if (!this.client) { - return Promise.resolve(); + return; + } + try { + await this.client.quit(); + } catch (err) { + logger.error('RedisCacheAdapter error on shutdown', { error: err }); } - return new Promise(resolve => { - this.client.quit(err => { - if (err) { - logger.error('RedisCacheAdapter error on shutdown', { error: err }); - } - resolve(); - }); - }); } - get(key) { + async get(key) { debug('get', { key }); - return this.queue.enqueue( - key, - () => - new Promise(resolve => { - this.client.get(key, function (err, res) { - debug('-> get', { key, res }); - if (!res) { - return resolve(null); - } - resolve(JSON.parse(res)); - }); - }) - ); + try { + await this.queue.enqueue(key); + const res = await this.client.get(key); + if (!res) { + return null; + } + return JSON.parse(res); + } catch (err) { + logger.error('RedisCacheAdapter error on get', { error: err }); + } } - put(key, value, ttl = this.ttl) { + async put(key, value, ttl = this.ttl) { value = JSON.stringify(value); debug('put', { key, value, ttl }); - + await this.queue.enqueue(key); if (ttl === 0) { // ttl of zero is a logical no-op, but redis cannot set expire time of zero - return this.queue.enqueue(key, () => Promise.resolve()); + return; } if (ttl === Infinity) { - return this.queue.enqueue( - key, - () => - new Promise(resolve => { - this.client.set(key, value, function () { - resolve(); - }); - }) - ); + return this.client.set(key, value); } if (!isValidTTL(ttl)) { ttl = this.ttl; } - - return this.queue.enqueue( - key, - () => - new Promise(resolve => { - this.client.psetex(key, ttl, value, function () { - resolve(); - }); - }) - ); + return this.client.set(key, value, { PX: ttl }); } - del(key) { + async del(key) { debug('del', { key }); - return this.queue.enqueue( - key, - () => - new Promise(resolve => { - this.client.del(key, function () { - resolve(); - }); - }) - ); + await this.queue.enqueue(key); + return this.client.del(key); } - clear() { + async clear() { debug('clear'); - return this.queue.enqueue( - FLUSH_DB_KEY, - () => - new Promise(resolve => { - this.client.flushdb(function () { - resolve(); - }); - }) - ); + await this.queue.enqueue(FLUSH_DB_KEY); + return this.client.sendCommand(['FLUSHDB']); } // Used for testing - async getAllKeys() { - return new Promise((resolve, reject) => { - this.client.keys('*', (err, keys) => { - if (err) { - reject(err); - } else { - resolve(keys); - } - }); - }); + getAllKeys() { + return this.client.keys('*'); } } diff --git a/src/Adapters/Email/MailAdapter.js b/src/Adapters/Email/MailAdapter.js index 791f9e6bd4..93069e2c27 100644 --- a/src/Adapters/Email/MailAdapter.js +++ b/src/Adapters/Email/MailAdapter.js @@ -1,9 +1,7 @@ /*eslint no-unused-vars: "off"*/ /** - * @module Adapters - */ -/** - * @interface MailAdapter + * @interface + * @memberof module:Adapters * Mail Adapter prototype * A MailAdapter should implement at least sendMail() */ diff --git a/src/Adapters/Files/FilesAdapter.js b/src/Adapters/Files/FilesAdapter.js index 68666b919a..afd06942e9 100644 --- a/src/Adapters/Files/FilesAdapter.js +++ b/src/Adapters/Files/FilesAdapter.js @@ -19,10 +19,8 @@ import type { Config } from '../../Config'; import Parse from 'parse/node'; /** - * @module Adapters - */ -/** - * @interface FilesAdapter + * @interface + * @memberof module:Adapters */ export class FilesAdapter { /** Responsible for storing the file in order to be retrieved later by its filename diff --git a/src/Adapters/Files/GridFSBucketAdapter.js b/src/Adapters/Files/GridFSBucketAdapter.js index 8ff4d2b8eb..76a8f25d1b 100644 --- a/src/Adapters/Files/GridFSBucketAdapter.js +++ b/src/Adapters/Files/GridFSBucketAdapter.js @@ -28,13 +28,21 @@ export class GridFSBucketAdapter extends FilesAdapter { this._algorithm = 'aes-256-gcm'; this._encryptionKey = encryptionKey !== undefined - ? crypto.createHash('sha256').update(String(encryptionKey)).digest('base64').substr(0, 32) + ? crypto + .createHash('sha256') + .update(String(encryptionKey)) + .digest('base64') + .substring(0, 32) : null; const defaultMongoOptions = { useNewUrlParser: true, useUnifiedTopology: true, }; - this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); + const _mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); + for (const key of ['enableSchemaHooks', 'schemaCacheTtl', 'maxTimeMS']) { + delete _mongoOptions[key]; + } + this._mongoOptions = _mongoOptions; } _connect() { @@ -134,8 +142,8 @@ export class GridFSBucketAdapter extends FilesAdapter { } async rotateEncryptionKey(options = {}) { - var fileNames = []; - var oldKeyFileAdapter = {}; + let fileNames = []; + let oldKeyFileAdapter = {}; const bucket = await this._getBucket(); if (options.oldKey !== undefined) { oldKeyFileAdapter = new GridFSBucketAdapter( @@ -154,51 +162,22 @@ export class GridFSBucketAdapter extends FilesAdapter { fileNames.push(file.filename); }); } - return new Promise(resolve => { - var fileNamesNotRotated = fileNames; - var fileNamesRotated = []; - var fileNameTotal = fileNames.length; - var fileNameIndex = 0; - fileNames.forEach(fileName => { - oldKeyFileAdapter - .getFileData(fileName) - .then(plainTextData => { - //Overwrite file with data encrypted with new key - this.createFile(fileName, plainTextData) - .then(() => { - fileNamesRotated.push(fileName); - fileNamesNotRotated = fileNamesNotRotated.filter(function (value) { - return value !== fileName; - }); - fileNameIndex += 1; - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated, - }); - } - }) - .catch(() => { - fileNameIndex += 1; - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated, - }); - } - }); - }) - .catch(() => { - fileNameIndex += 1; - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated, - }); - } - }); - }); - }); + let fileNamesNotRotated = fileNames; + const fileNamesRotated = []; + for (const fileName of fileNames) { + try { + const plainTextData = await oldKeyFileAdapter.getFileData(fileName); + // Overwrite file with data encrypted with new key + await this.createFile(fileName, plainTextData); + fileNamesRotated.push(fileName); + fileNamesNotRotated = fileNamesNotRotated.filter(function (value) { + return value !== fileName; + }); + } catch (err) { + continue; + } + } + return { rotated: fileNamesRotated, notRotated: fileNamesNotRotated }; } getFileLocation(config, filename) { @@ -254,7 +233,7 @@ export class GridFSBucketAdapter extends FilesAdapter { stream.on('data', chunk => { res.write(chunk); }); - stream.on('error', (e) => { + stream.on('error', e => { res.status(404); res.send(e.message); }); diff --git a/src/Adapters/Logger/LoggerAdapter.js b/src/Adapters/Logger/LoggerAdapter.js index 21df5ccd48..3853d5f480 100644 --- a/src/Adapters/Logger/LoggerAdapter.js +++ b/src/Adapters/Logger/LoggerAdapter.js @@ -1,9 +1,7 @@ /*eslint no-unused-vars: "off"*/ /** - * @module Adapters - */ -/** - * @interface LoggerAdapter + * @interface + * @memberof module:Adapters * Logger Adapter * Allows you to change the logger mechanism * Default is WinstonLoggerAdapter.js diff --git a/src/Adapters/PubSub/PubSubAdapter.js b/src/Adapters/PubSub/PubSubAdapter.js index 9e6b13dfc7..728dff90e8 100644 --- a/src/Adapters/PubSub/PubSubAdapter.js +++ b/src/Adapters/PubSub/PubSubAdapter.js @@ -1,9 +1,7 @@ /*eslint no-unused-vars: "off"*/ /** - * @module Adapters - */ -/** - * @interface PubSubAdapter + * @interface + * @memberof module:Adapters */ export class PubSubAdapter { /** diff --git a/src/Adapters/PubSub/RedisPubSub.js b/src/Adapters/PubSub/RedisPubSub.js index e259f09a3b..cc2b3a9792 100644 --- a/src/Adapters/PubSub/RedisPubSub.js +++ b/src/Adapters/PubSub/RedisPubSub.js @@ -1,13 +1,13 @@ -import redis from 'redis'; +import { createClient } from 'redis'; function createPublisher({ redisURL, redisOptions = {} }): any { redisOptions.no_ready_check = true; - return redis.createClient(redisURL, redisOptions); + return createClient({ url: redisURL, ...redisOptions }); } function createSubscriber({ redisURL, redisOptions = {} }): any { redisOptions.no_ready_check = true; - return redis.createClient(redisURL, redisOptions); + return createClient({ url: redisURL, ...redisOptions }); } const RedisPubSub = { diff --git a/src/Adapters/Push/PushAdapter.js b/src/Adapters/Push/PushAdapter.js index 191fa15b40..fb0adbf469 100644 --- a/src/Adapters/Push/PushAdapter.js +++ b/src/Adapters/Push/PushAdapter.js @@ -12,10 +12,8 @@ // android push and APNS for ios push. /** - * @module Adapters - */ -/** - * @interface PushAdapter + * @interface + * @memberof module:Adapters */ export class PushAdapter { /** diff --git a/src/Adapters/Storage/Mongo/MongoCollection.js b/src/Adapters/Storage/Mongo/MongoCollection.js index f3f089f0f1..4f02c5c8fa 100644 --- a/src/Adapters/Storage/Mongo/MongoCollection.js +++ b/src/Adapters/Storage/Mongo/MongoCollection.js @@ -15,7 +15,18 @@ export default class MongoCollection { // idea. Or even if this behavior is a good idea. find( query, - { skip, limit, sort, keys, maxTimeMS, readPreference, hint, caseInsensitive, explain } = {} + { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain, + comment, + } = {} ) { // Support for Full Text Search - $text if (keys && keys.$score) { @@ -32,6 +43,7 @@ export default class MongoCollection { hint, caseInsensitive, explain, + comment, }).catch(error => { // Check for "no geoindex" error if (error.code != 17007 && !error.message.match(/unable to find index for .geoNear/)) { @@ -60,6 +72,7 @@ export default class MongoCollection { hint, caseInsensitive, explain, + comment, }) ) ); @@ -75,7 +88,18 @@ export default class MongoCollection { _rawFind( query, - { skip, limit, sort, keys, maxTimeMS, readPreference, hint, caseInsensitive, explain } = {} + { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain, + comment, + } = {} ) { let findOperation = this._mongoCollection.find(query, { skip, @@ -83,6 +107,7 @@ export default class MongoCollection { sort, readPreference, hint, + comment, }); if (keys) { @@ -100,7 +125,7 @@ export default class MongoCollection { return explain ? findOperation.explain(explain) : findOperation.toArray(); } - count(query, { skip, limit, sort, maxTimeMS, readPreference, hint } = {}) { + count(query, { skip, limit, sort, maxTimeMS, readPreference, hint, comment } = {}) { // If query is empty, then use estimatedDocumentCount instead. // This is due to countDocuments performing a scan, // which greatly increases execution time when being run on large collections. @@ -118,6 +143,7 @@ export default class MongoCollection { maxTimeMS, readPreference, hint, + comment, }); return countOperation; @@ -127,9 +153,9 @@ export default class MongoCollection { return this._mongoCollection.distinct(field, query); } - aggregate(pipeline, { maxTimeMS, readPreference, hint, explain } = {}) { + aggregate(pipeline, { maxTimeMS, readPreference, hint, explain, comment } = {}) { return this._mongoCollection - .aggregate(pipeline, { maxTimeMS, readPreference, hint, explain }) + .aggregate(pipeline, { maxTimeMS, readPreference, hint, explain, comment }) .toArray(); } @@ -160,18 +186,10 @@ export default class MongoCollection { } _ensureSparseUniqueIndexInBackground(indexRequest) { - return new Promise((resolve, reject) => { - this._mongoCollection.createIndex( - indexRequest, - { unique: true, background: true, sparse: true }, - error => { - if (error) { - reject(error); - } else { - resolve(); - } - } - ); + return this._mongoCollection.createIndex(indexRequest, { + unique: true, + background: true, + sparse: true, }); } diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index c0d4c0ca9e..e9d49b2ecf 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -139,11 +139,12 @@ export class MongoStorageAdapter implements StorageAdapter { _maxTimeMS: ?number; canSortOnJoinTables: boolean; enableSchemaHooks: boolean; + schemaCacheTtl: ?number; constructor({ uri = defaults.DefaultMongoURI, collectionPrefix = '', mongoOptions = {} }: any) { this._uri = uri; this._collectionPrefix = collectionPrefix; - this._mongoOptions = mongoOptions; + this._mongoOptions = { ...mongoOptions }; this._mongoOptions.useNewUrlParser = true; this._mongoOptions.useUnifiedTopology = true; this._onchange = () => {}; @@ -152,8 +153,11 @@ export class MongoStorageAdapter implements StorageAdapter { this._maxTimeMS = mongoOptions.maxTimeMS; this.canSortOnJoinTables = true; this.enableSchemaHooks = !!mongoOptions.enableSchemaHooks; - delete mongoOptions.enableSchemaHooks; - delete mongoOptions.maxTimeMS; + this.schemaCacheTtl = mongoOptions.schemaCacheTtl; + for (const key of ['enableSchemaHooks', 'schemaCacheTtl', 'maxTimeMS']) { + delete mongoOptions[key]; + delete this._mongoOptions[key]; + } } watch(callback: () => void): void { @@ -168,7 +172,6 @@ export class MongoStorageAdapter implements StorageAdapter { // parsing and re-formatting causes the auth value (if there) to get URI // encoded const encodedUri = formatUrl(parseUrl(this._uri)); - this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) .then(client => { // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client @@ -208,11 +211,12 @@ export class MongoStorageAdapter implements StorageAdapter { throw error; } - handleShutdown() { + async handleShutdown() { if (!this.client) { - return Promise.resolve(); + return; } - return this.client.close(false); + await this.client.close(false); + delete this.connectionPromise; } _adaptiveCollection(name: string) { @@ -599,7 +603,17 @@ export class MongoStorageAdapter implements StorageAdapter { className: string, schema: SchemaType, query: QueryType, - { skip, limit, sort, keys, readPreference, hint, caseInsensitive, explain }: QueryOptions + { + skip, + limit, + sort, + keys, + readPreference, + hint, + caseInsensitive, + explain, + comment, + }: QueryOptions ): Promise { validateExplainValue(explain); schema = convertParseSchemaToMongoSchema(schema); @@ -642,6 +656,7 @@ export class MongoStorageAdapter implements StorageAdapter { hint, caseInsensitive, explain, + comment, }) ) .then(objects => { @@ -682,13 +697,8 @@ export class MongoStorageAdapter implements StorageAdapter { }; return this._adaptiveCollection(className) - .then( - collection => - new Promise((resolve, reject) => - collection._mongoCollection.createIndex(indexCreationRequest, indexOptions, error => - error ? reject(error) : resolve() - ) - ) + .then(collection => + collection._mongoCollection.createIndex(indexCreationRequest, indexOptions) ) .catch(err => this.handleError(err)); } @@ -736,7 +746,9 @@ export class MongoStorageAdapter implements StorageAdapter { schema: SchemaType, query: QueryType, readPreference: ?string, - hint: ?mixed + _estimate: ?boolean, + hint: ?mixed, + comment: ?string ) { schema = convertParseSchemaToMongoSchema(schema); readPreference = this._parseReadPreference(readPreference); @@ -746,6 +758,7 @@ export class MongoStorageAdapter implements StorageAdapter { maxTimeMS: this._maxTimeMS, readPreference, hint, + comment, }) ) .catch(err => this.handleError(err)); @@ -778,7 +791,8 @@ export class MongoStorageAdapter implements StorageAdapter { pipeline: any, readPreference: ?string, hint: ?mixed, - explain?: boolean + explain?: boolean, + comment: ?string ) { validateExplainValue(explain); let isPointerField = false; @@ -812,6 +826,7 @@ export class MongoStorageAdapter implements StorageAdapter { maxTimeMS: this._maxTimeMS, hint, explain, + comment, }) ) .then(results => { diff --git a/src/Adapters/Storage/Mongo/MongoTransform.js b/src/Adapters/Storage/Mongo/MongoTransform.js index 91ad23fa4a..336d9affc9 100644 --- a/src/Adapters/Storage/Mongo/MongoTransform.js +++ b/src/Adapters/Storage/Mongo/MongoTransform.js @@ -188,6 +188,16 @@ const transformInteriorValue = restValue => { // Handle atomic values var value = transformInteriorAtom(restValue); if (value !== CannotTransform) { + if (value && typeof value === 'object') { + if (value instanceof Date) { + return value; + } + if (value instanceof Array) { + value = value.map(transformInteriorValue); + } else { + value = mapValues(value, transformInteriorValue); + } + } return value; } @@ -447,6 +457,7 @@ const parseObjectKeyValueToMongoObjectKeyValue = (restKey, restValue, schema) => ); } value = mapValues(restValue, transformInteriorValue); + return { key: restKey, value }; }; @@ -976,6 +987,13 @@ function transformUpdateOperator({ __op, amount, objects }, flatten) { return { __op: '$inc', arg: amount }; } + case 'SetOnInsert': + if (flatten) { + return amount; + } else { + return { __op: '$setOnInsert', arg: amount }; + } + case 'Add': case 'AddUnique': if (!(objects instanceof Array)) { diff --git a/src/Adapters/Storage/Postgres/PostgresConfigParser.js b/src/Adapters/Storage/Postgres/PostgresConfigParser.js index d86778cf20..64e4752913 100644 --- a/src/Adapters/Storage/Postgres/PostgresConfigParser.js +++ b/src/Adapters/Storage/Postgres/PostgresConfigParser.js @@ -58,7 +58,7 @@ function getDatabaseOptionsFromURI(uri) { databaseOptions.fallback_application_name = queryParams.fallback_application_name; if (queryParams.poolSize) { - databaseOptions.poolSize = parseInt(queryParams.poolSize) || 10; + databaseOptions.max = parseInt(queryParams.poolSize) || 10; } if (queryParams.max) { databaseOptions.max = parseInt(queryParams.max) || 10; diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index eb668868c6..efbe985bf9 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -231,7 +231,7 @@ const transformAggregateField = fieldName => { if (fieldName === '$_updated_at') { return 'updatedAt'; } - return fieldName.substr(1); + return fieldName.substring(1); }; const validateKeys = object => { @@ -289,7 +289,6 @@ const buildWhereClause = ({ schema, query, index, caseInsensitive }): WhereClaus continue; } } - const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); if (authDataMatch) { // TODO: Handle querying by _auth_data_provider, authData is stored in authData field @@ -851,13 +850,18 @@ export class PostgresStorageAdapter implements StorageAdapter { _pgp: any; _stream: any; _uuid: any; + schemaCacheTtl: ?number; constructor({ uri, collectionPrefix = '', databaseOptions = {} }: any) { + const options = { ...databaseOptions }; this._collectionPrefix = collectionPrefix; this.enableSchemaHooks = !!databaseOptions.enableSchemaHooks; - delete databaseOptions.enableSchemaHooks; + this.schemaCacheTtl = databaseOptions.schemaCacheTtl; + for (const key of ['enableSchemaHooks', 'schemaCacheTtl']) { + delete options[key]; + } - const { client, pgp } = createClient(uri, databaseOptions); + const { client, pgp } = createClient(uri, options); this._client = client; this._onchange = () => {}; this._pgp = pgp; @@ -1190,7 +1194,9 @@ export class PostgresStorageAdapter implements StorageAdapter { const now = new Date().getTime(); const helpers = this._pgp.helpers; debug('deleteAllClasses'); - + if (this._client?.$pool.ended) { + return; + } await this._client .task('delete-all-classes', async t => { try { @@ -1322,12 +1328,17 @@ export class PostgresStorageAdapter implements StorageAdapter { return; } var authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + const authDataAlreadyExists = !!object.authData; if (authDataMatch) { var provider = authDataMatch[1]; object['authData'] = object['authData'] || {}; object['authData'][provider] = object[fieldName]; delete object[fieldName]; fieldName = 'authData'; + // Avoid adding authData multiple times to the query + if (authDataAlreadyExists) { + return; + } } columnsArray.push(fieldName); @@ -1807,7 +1818,6 @@ export class PostgresStorageAdapter implements StorageAdapter { caseInsensitive, }); values.push(...where.values); - const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; const limitPattern = hasLimit ? `LIMIT $${values.length + 1}` : ''; if (hasLimit) { @@ -1911,14 +1921,14 @@ export class PostgresStorageAdapter implements StorageAdapter { }; } if (object[fieldName] && schema.fields[fieldName].type === 'Polygon') { - let coords = object[fieldName]; - coords = coords.substr(2, coords.length - 4).split('),('); - coords = coords.map(point => { + let coords = new String(object[fieldName]); + coords = coords.substring(2, coords.length - 2).split('),('); + const updatedCoords = coords.map(point => { return [parseFloat(point.split(',')[1]), parseFloat(point.split(',')[0])]; }); object[fieldName] = { __type: 'Polygon', - coordinates: coords, + coordinates: updatedCoords, }; } if (object[fieldName] && schema.fields[fieldName].type === 'File') { @@ -2238,8 +2248,11 @@ export class PostgresStorageAdapter implements StorageAdapter { }); stage.$match = collapse; } - for (const field in stage.$match) { + for (let field in stage.$match) { const value = stage.$match[field]; + if (field === '_id') { + field = 'objectId'; + } const matchPatterns = []; Object.keys(ParseToPosgresComparator).forEach(cmp => { if (value[cmp]) { @@ -2621,7 +2634,7 @@ function literalizeRegexPart(s: string) { const result1: any = s.match(matcher1); if (result1 && result1.length > 1 && result1.index > -1) { // process regex that has a beginning and an end specified for the literal text - const prefix = s.substr(0, result1.index); + const prefix = s.substring(0, result1.index); const remaining = result1[1]; return literalizeRegexPart(prefix) + createLiteralRegex(remaining); @@ -2631,7 +2644,7 @@ function literalizeRegexPart(s: string) { const matcher2 = /\\Q((?!\\E).*)$/; const result2: any = s.match(matcher2); if (result2 && result2.length > 1 && result2.index > -1) { - const prefix = s.substr(0, result2.index); + const prefix = s.substring(0, result2.index); const remaining = result2[1]; return literalizeRegexPart(prefix) + createLiteralRegex(remaining); @@ -2643,7 +2656,7 @@ function literalizeRegexPart(s: string) { .replace(/([^\\])(\\Q)/, '$1') .replace(/^\\E/, '') .replace(/^\\Q/, '') - .replace(/([^'])'/, `$1''`) + .replace(/([^'])'/g, `$1''`) .replace(/^'([^'])/, `''$1`); } diff --git a/src/Adapters/Storage/StorageAdapter.js b/src/Adapters/Storage/StorageAdapter.js index 6e4573b748..d25c9753c0 100644 --- a/src/Adapters/Storage/StorageAdapter.js +++ b/src/Adapters/Storage/StorageAdapter.js @@ -19,6 +19,7 @@ export type QueryOptions = { caseInsensitive?: boolean, action?: string, addsField?: boolean, + comment?: string, }; export type UpdateQueryOptions = { @@ -30,6 +31,8 @@ export type FullQueryOptions = QueryOptions & UpdateQueryOptions; export interface StorageAdapter { canSortOnJoinTables: boolean; + schemaCacheTtl: ?number; + enableSchemaHooks: boolean; classExists(className: string): Promise; setClassLevelPermissions(className: string, clps: any): Promise; @@ -95,7 +98,8 @@ export interface StorageAdapter { query: QueryType, readPreference?: string, estimate?: boolean, - hint?: mixed + hint?: mixed, + comment?: string ): Promise; distinct( className: string, @@ -109,7 +113,8 @@ export interface StorageAdapter { pipeline: any, readPreference: ?string, hint: ?mixed, - explain?: boolean + explain?: boolean, + comment?: string ): Promise; performInitialization(options: ?any): Promise; watch(callback: () => void): void; diff --git a/src/Adapters/WebSocketServer/WSSAdapter.js b/src/Adapters/WebSocketServer/WSSAdapter.js index 007cacdf76..a810c03f9d 100644 --- a/src/Adapters/WebSocketServer/WSSAdapter.js +++ b/src/Adapters/WebSocketServer/WSSAdapter.js @@ -11,10 +11,8 @@ // Default is WSAdapter. The above functions will be binded. /** - * @module Adapters - */ -/** - * @interface WSSAdapter + * @interface + * @memberof module:Adapters */ export class WSSAdapter { /** diff --git a/src/Auth.js b/src/Auth.js index ce5c71c860..f21ba96c6c 100644 --- a/src/Auth.js +++ b/src/Auth.js @@ -1,5 +1,9 @@ -const RestQuery = require('./RestQuery'); const Parse = require('parse/node'); +import { isDeepStrictEqual } from 'util'; +import { getRequestObject, resolveError } from './triggers'; +import { logger } from './logger'; +import RestQuery from './RestQuery'; +import RestWrite from './RestWrite'; // An Auth object tells you who is requesting something and whether // the master key was used. @@ -8,6 +12,7 @@ function Auth({ config, cacheController = undefined, isMaster = false, + isMaintenance = false, isReadOnly = false, user, installationId, @@ -16,6 +21,7 @@ function Auth({ this.cacheController = cacheController || (config && config.cacheController); this.installationId = installationId; this.isMaster = isMaster; + this.isMaintenance = isMaintenance; this.user = user; this.isReadOnly = isReadOnly; @@ -32,6 +38,9 @@ Auth.prototype.isUnauthenticated = function () { if (this.isMaster) { return false; } + if (this.isMaintenance) { + return false; + } if (this.user) { return false; } @@ -43,6 +52,11 @@ function master(config) { return new Auth({ config, isMaster: true }); } +// A helper to get a maintenance-level Auth object +function maintenance(config) { + return new Auth({ config, isMaintenance: true }); +} + // A helper to get a master-level Auth object function readOnly(config) { return new Auth({ config, isMaster: true, isReadOnly: true }); @@ -53,6 +67,49 @@ function nobody(config) { return new Auth({ config, isMaster: false }); } +const throttle = {}; +const renewSessionIfNeeded = async ({ config, session, sessionToken }) => { + if (!config?.extendSessionOnUse) { + return; + } + clearTimeout(throttle[sessionToken]); + throttle[sessionToken] = setTimeout(async () => { + try { + if (!session) { + const query = await RestQuery({ + method: RestQuery.Method.get, + config, + auth: master(config), + runBeforeFind: false, + className: '_Session', + restWhere: { sessionToken }, + restOptions: { limit: 1 }, + }); + const { results } = await query.execute(); + session = results[0]; + } + const lastUpdated = new Date(session?.updatedAt); + const yesterday = new Date(); + yesterday.setDate(yesterday.getDate() - 1); + if (lastUpdated > yesterday || !session) { + return; + } + const expiresAt = config.generateSessionExpiresAt(); + await new RestWrite( + config, + master(config), + '_Session', + { objectId: session.objectId }, + { expiresAt: Parse._encode(expiresAt) } + ).execute(); + } catch (e) { + if (e?.code !== Parse.Error.OBJECT_NOT_FOUND) { + logger.error('Could not update session expiry: ', e); + } + } + }, 500); +}; + // Returns a promise that resolves to an Auth object const getAuthForSessionToken = async function ({ config, @@ -65,6 +122,7 @@ const getAuthForSessionToken = async function ({ const userJSON = await cacheController.user.get(sessionToken); if (userJSON) { const cachedUser = Parse.Object.fromJSON(userJSON); + renewSessionIfNeeded({ config, sessionToken }); return Promise.resolve( new Auth({ config, @@ -83,8 +141,16 @@ const getAuthForSessionToken = async function ({ limit: 1, include: 'user', }; - - const query = new RestQuery(config, master(config), '_Session', { sessionToken }, restOptions); + const RestQuery = require('./RestQuery'); + const query = await RestQuery({ + method: RestQuery.Method.get, + config, + runBeforeFind: false, + auth: master(config), + className: '_Session', + restWhere: { sessionToken }, + restOptions, + }); results = (await query.execute()).results; } else { results = ( @@ -99,18 +165,20 @@ const getAuthForSessionToken = async function ({ if (results.length !== 1 || !results[0]['user']) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); } + const session = results[0]; const now = new Date(), - expiresAt = results[0].expiresAt ? new Date(results[0].expiresAt.iso) : undefined; + expiresAt = session.expiresAt ? new Date(session.expiresAt.iso) : undefined; if (expiresAt < now) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.'); } - const obj = results[0]['user']; + const obj = session.user; delete obj.password; obj['className'] = '_User'; obj['sessionToken'] = sessionToken; if (cacheController) { cacheController.user.put(sessionToken, obj); } + renewSessionIfNeeded({ config, session, sessionToken }); const userObject = Parse.Object.fromJSON(obj); return new Auth({ config, @@ -121,11 +189,20 @@ const getAuthForSessionToken = async function ({ }); }; -var getAuthForLegacySessionToken = function ({ config, sessionToken, installationId }) { +var getAuthForLegacySessionToken = async function ({ config, sessionToken, installationId }) { var restOptions = { limit: 1, }; - var query = new RestQuery(config, master(config), '_User', { sessionToken }, restOptions); + const RestQuery = require('./RestQuery'); + var query = await RestQuery({ + method: RestQuery.Method.get, + config, + runBeforeFind: false, + auth: master(config), + className: '_User', + restWhere: { _session_token: sessionToken }, + restOptions, + }); return query.execute().then(response => { var results = response.results; if (results.length !== 1) { @@ -145,7 +222,7 @@ var getAuthForLegacySessionToken = function ({ config, sessionToken, installatio // Returns a promise that resolves to an array of role names Auth.prototype.getUserRoles = function () { - if (this.isMaster || !this.user) { + if (this.isMaster || this.isMaintenance || !this.user) { return Promise.resolve([]); } if (this.fetchedRoles) { @@ -169,9 +246,16 @@ Auth.prototype.getRolesForUser = async function () { objectId: this.user.id, }, }; - await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => - results.push(result) - ); + const RestQuery = require('./RestQuery'); + const query = await RestQuery({ + method: RestQuery.Method.find, + runBeforeFind: false, + config: this.config, + auth: master(this.config), + className: '_Role', + restWhere, + }); + await query.each(result => results.push(result)); } else { await new Parse.Query(Parse.Role) .equalTo('users', this.user) @@ -262,9 +346,16 @@ Auth.prototype.getRolesByIds = async function (ins) { }; }); const restWhere = { roles: { $in: roles } }; - await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => - results.push(result) - ); + const RestQuery = require('./RestQuery'); + const query = await RestQuery({ + method: RestQuery.Method.find, + config: this.config, + runBeforeFind: false, + auth: master(this.config), + className: '_Role', + restWhere, + }); + await query.each(result => results.push(result)); } return results; }; @@ -307,11 +398,191 @@ Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], quer }); }; +const findUsersWithAuthData = (config, authData) => { + const providers = Object.keys(authData); + const query = providers + .reduce((memo, provider) => { + if (!authData[provider] || (authData && !authData[provider].id)) { + return memo; + } + const queryKey = `authData.${provider}.id`; + const query = {}; + query[queryKey] = authData[provider].id; + memo.push(query); + return memo; + }, []) + .filter(q => { + return typeof q !== 'undefined'; + }); + + return query.length > 0 + ? config.database.find('_User', { $or: query }, { limit: 2 }) + : Promise.resolve([]); +}; + +const hasMutatedAuthData = (authData, userAuthData) => { + if (!userAuthData) return { hasMutatedAuthData: true, mutatedAuthData: authData }; + const mutatedAuthData = {}; + Object.keys(authData).forEach(provider => { + // Anonymous provider is not handled this way + if (provider === 'anonymous') return; + const providerData = authData[provider]; + const userProviderAuthData = userAuthData[provider]; + if (!isDeepStrictEqual(providerData, userProviderAuthData)) { + mutatedAuthData[provider] = providerData; + } + }); + const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; + return { hasMutatedAuthData, mutatedAuthData }; +}; + +const checkIfUserHasProvidedConfiguredProvidersForLogin = ( + req = {}, + authData = {}, + userAuthData = {}, + config +) => { + const savedUserProviders = Object.keys(userAuthData).map(provider => ({ + name: provider, + adapter: config.authDataManager.getValidatorForProvider(provider).adapter, + })); + + const hasProvidedASoloProvider = savedUserProviders.some( + provider => + provider && provider.adapter && provider.adapter.policy === 'solo' && authData[provider.name] + ); + + // Solo providers can be considered as safe, so we do not have to check if the user needs + // to provide an additional provider to login. An auth adapter with "solo" (like webauthn) means + // no "additional" auth needs to be provided to login (like OTP, MFA) + if (hasProvidedASoloProvider) { + return; + } + + const additionProvidersNotFound = []; + const hasProvidedAtLeastOneAdditionalProvider = savedUserProviders.some(provider => { + let policy = provider.adapter.policy; + if (typeof policy === 'function') { + const requestObject = { + ip: req.config.ip, + user: req.auth.user, + master: req.auth.isMaster, + }; + policy = policy.call(provider.adapter, requestObject, userAuthData[provider.name]); + } + if (policy === 'additional') { + if (authData[provider.name]) { + return true; + } else { + // Push missing provider for error message + additionProvidersNotFound.push(provider.name); + } + } + }); + if (hasProvidedAtLeastOneAdditionalProvider || !additionProvidersNotFound.length) { + return; + } + + throw new Parse.Error( + Parse.Error.OTHER_CAUSE, + `Missing additional authData ${additionProvidersNotFound.join(',')}` + ); +}; + +// Validate each authData step-by-step and return the provider responses +const handleAuthDataValidation = async (authData, req, foundUser) => { + let user; + if (foundUser) { + user = Parse.User.fromJSON({ className: '_User', ...foundUser }); + // Find user by session and current objectId; only pass user if it's the current user or master key is provided + } else if ( + (req.auth && + req.auth.user && + typeof req.getUserId === 'function' && + req.getUserId() === req.auth.user.id) || + (req.auth && req.auth.isMaster && typeof req.getUserId === 'function' && req.getUserId()) + ) { + user = new Parse.User(); + user.id = req.auth.isMaster ? req.getUserId() : req.auth.user.id; + await user.fetch({ useMasterKey: true }); + } + + const { updatedObject } = req.buildParseObjects(); + const requestObject = getRequestObject(undefined, req.auth, updatedObject, user, req.config); + // Perform validation as step-by-step pipeline for better error consistency + // and also to avoid to trigger a provider (like OTP SMS) if another one fails + const acc = { authData: {}, authDataResponse: {} }; + const authKeys = Object.keys(authData).sort(); + for (const provider of authKeys) { + let method = ''; + try { + if (authData[provider] === null) { + acc.authData[provider] = null; + continue; + } + const { validator } = req.config.authDataManager.getValidatorForProvider(provider); + const authProvider = (req.config.auth || {})[provider] || {}; + if (!validator || authProvider.enabled === false) { + throw new Parse.Error( + Parse.Error.UNSUPPORTED_SERVICE, + 'This authentication method is unsupported.' + ); + } + let validationResult = await validator(authData[provider], req, user, requestObject); + method = validationResult && validationResult.method; + requestObject.triggerName = method; + if (validationResult && validationResult.validator) { + validationResult = await validationResult.validator(); + } + if (!validationResult) { + acc.authData[provider] = authData[provider]; + continue; + } + if (!Object.keys(validationResult).length) { + acc.authData[provider] = authData[provider]; + continue; + } + + if (validationResult.response) { + acc.authDataResponse[provider] = validationResult.response; + } + // Some auth providers after initialization will avoid to replace authData already stored + if (!validationResult.doNotSave) { + acc.authData[provider] = validationResult.save || authData[provider]; + } + } catch (err) { + const e = resolveError(err, { + code: Parse.Error.SCRIPT_FAILED, + message: 'Auth failed. Unknown error.', + }); + const userString = + req.auth && req.auth.user ? req.auth.user.id : req.data.objectId || undefined; + logger.error( + `Failed running auth step ${method} for ${provider} for user ${userString} with Error: ` + + JSON.stringify(e), + { + authenticationStep: method, + error: e, + user: userString, + provider, + } + ); + throw e; + } + } + return acc; +}; + module.exports = { Auth, master, + maintenance, nobody, readOnly, getAuthForSessionToken, getAuthForLegacySessionToken, + findUsersWithAuthData, + hasMutatedAuthData, + checkIfUserHasProvidedConfiguredProvidersForLogin, + handleAuthDataValidation, }; diff --git a/src/Config.js b/src/Config.js index 9c5fb3bc83..933cf39858 100644 --- a/src/Config.js +++ b/src/Config.js @@ -2,26 +2,31 @@ // configured. // mount is the URL for the root of the API; includes http, domain, etc. +import { isBoolean, isString } from 'lodash'; +import net from 'net'; import AppCache from './cache'; import DatabaseController from './Controllers/DatabaseController'; -import net from 'net'; +import { logLevels as validLogLevels } from './Controllers/LoggerController'; +import { version } from '../package.json'; import { - IdempotencyOptions, - FileUploadOptions, AccountLockoutOptions, + DatabaseOptions, + FileUploadOptions, + IdempotencyOptions, + LogLevels, PagesOptions, - SecurityOptions, - SchemaOptions, ParseServerOptions, + SchemaOptions, + SecurityOptions, } from './Options/Definitions'; -import { isBoolean, isString } from 'lodash'; +import ParseServer from './cloud-code/Parse.Server'; function removeTrailingSlash(str) { if (!str) { return str; } if (str.endsWith('/')) { - str = str.substr(0, str.length - 1); + str = str.substring(0, str.length - 1); } return str; } @@ -46,55 +51,53 @@ export class Config { config.generateEmailVerifyTokenExpiresAt = config.generateEmailVerifyTokenExpiresAt.bind( config ); + config.version = version; return config; } static put(serverConfiguration) { - Config.validate(serverConfiguration); + Config.validateOptions(serverConfiguration); + Config.validateControllers(serverConfiguration); AppCache.put(serverConfiguration.appId, serverConfiguration); Config.setupPasswordValidator(serverConfiguration.passwordPolicy); return serverConfiguration; } - static validate({ - verifyUserEmails, - userController, - appName, + static validateOptions({ publicServerURL, revokeSessionOnPasswordReset, expireInactiveSessions, sessionLength, defaultLimit, maxLimit, - emailVerifyTokenValidityDuration, accountLockout, passwordPolicy, masterKeyIps, masterKey, + maintenanceKey, + maintenanceKeyIps, readOnlyMasterKey, allowHeaders, idempotencyOptions, - emailVerifyTokenReuseIfValid, fileUpload, pages, security, enforcePrivateUsers, schema, requestKeywordDenylist, + allowExpiredAuthDataToken, + logLevels, + rateLimit, + databaseOptions, + extendSessionOnUse, + allowClientClassCreation, }) { if (masterKey === readOnlyMasterKey) { throw new Error('masterKey and readOnlyMasterKey should be different'); } - const emailAdapter = userController.adapter; - if (verifyUserEmails) { - this.validateEmailConfiguration({ - emailAdapter, - appName, - publicServerURL, - emailVerifyTokenValidityDuration, - emailVerifyTokenReuseIfValid, - }); + if (masterKey === maintenanceKey) { + throw new Error('masterKey and maintenanceKey should be different'); } this.validateAccountLockoutPolicy(accountLockout); @@ -105,13 +108,18 @@ export class Config { throw 'revokeSessionOnPasswordReset must be a boolean value'; } + if (typeof extendSessionOnUse !== 'boolean') { + throw 'extendSessionOnUse must be a boolean value'; + } + if (publicServerURL) { if (!publicServerURL.startsWith('http://') && !publicServerURL.startsWith('https://')) { throw 'publicServerURL should be a valid HTTPS URL starting with https://'; } } this.validateSessionConfiguration(sessionLength, expireInactiveSessions); - this.validateMasterKeyIps(masterKeyIps); + this.validateIps('masterKeyIps', masterKeyIps); + this.validateIps('maintenanceKeyIps', maintenanceKeyIps); this.validateDefaultLimit(defaultLimit); this.validateMaxLimit(maxLimit); this.validateAllowHeaders(allowHeaders); @@ -120,7 +128,32 @@ export class Config { this.validateSecurityOptions(security); this.validateSchemaOptions(schema); this.validateEnforcePrivateUsers(enforcePrivateUsers); + this.validateAllowExpiredAuthDataToken(allowExpiredAuthDataToken); this.validateRequestKeywordDenylist(requestKeywordDenylist); + this.validateRateLimit(rateLimit); + this.validateLogLevels(logLevels); + this.validateDatabaseOptions(databaseOptions); + this.validateAllowClientClassCreation(allowClientClassCreation); + } + + static validateControllers({ + verifyUserEmails, + userController, + appName, + publicServerURL, + emailVerifyTokenValidityDuration, + emailVerifyTokenReuseIfValid, + }) { + const emailAdapter = userController.adapter; + if (verifyUserEmails) { + this.validateEmailConfiguration({ + emailAdapter, + appName, + publicServerURL, + emailVerifyTokenValidityDuration, + emailVerifyTokenReuseIfValid, + }); + } } static validateRequestKeywordDenylist(requestKeywordDenylist) { @@ -137,6 +170,18 @@ export class Config { } } + static validateAllowExpiredAuthDataToken(allowExpiredAuthDataToken) { + if (typeof allowExpiredAuthDataToken !== 'boolean') { + throw 'Parse Server option allowExpiredAuthDataToken must be a boolean.'; + } + } + + static validateAllowClientClassCreation(allowClientClassCreation) { + if (typeof allowClientClassCreation !== 'boolean') { + throw 'Parse Server option allowClientClassCreation must be a boolean.'; + } + } + static validateSecurityOptions(security) { if (Object.prototype.toString.call(security) !== '[object Object]') { throw 'Parse Server option security must be an object.'; @@ -355,6 +400,13 @@ export class Config { if (passwordPolicy.resetTokenReuseIfValid && !passwordPolicy.resetTokenValidityDuration) { throw 'You cannot use resetTokenReuseIfValid without resetTokenValidityDuration'; } + + if ( + passwordPolicy.resetPasswordSuccessOnInvalidEmail && + typeof passwordPolicy.resetPasswordSuccessOnInvalidEmail !== 'boolean' + ) { + throw 'resetPasswordSuccessOnInvalidEmail must be a boolean value'; + } } } @@ -424,12 +476,20 @@ export class Config { } else if (typeof fileUpload.enableForAuthenticatedUser !== 'boolean') { throw 'fileUpload.enableForAuthenticatedUser must be a boolean value.'; } + if (fileUpload.fileExtensions === undefined) { + fileUpload.fileExtensions = FileUploadOptions.fileExtensions.default; + } else if (!Array.isArray(fileUpload.fileExtensions)) { + throw 'fileUpload.fileExtensions must be an array.'; + } } - static validateMasterKeyIps(masterKeyIps) { - for (const ip of masterKeyIps) { + static validateIps(field, masterKeyIps) { + for (let ip of masterKeyIps) { + if (ip.includes('/')) { + ip = ip.split('/')[0]; + } if (!net.isIP(ip)) { - throw `Invalid ip in masterKeyIps: ${ip}`; + throw `The Parse Server option "${field}" contains an invalid IP address "${ip}".`; } } } @@ -490,6 +550,84 @@ export class Config { } } + static validateLogLevels(logLevels) { + for (const key of Object.keys(LogLevels)) { + if (logLevels[key]) { + if (validLogLevels.indexOf(logLevels[key]) === -1) { + throw `'${key}' must be one of ${JSON.stringify(validLogLevels)}`; + } + } else { + logLevels[key] = LogLevels[key].default; + } + } + } + + static validateDatabaseOptions(databaseOptions) { + if (databaseOptions == undefined) { + return; + } + if (Object.prototype.toString.call(databaseOptions) !== '[object Object]') { + throw `databaseOptions must be an object`; + } + if (databaseOptions.enableSchemaHooks === undefined) { + databaseOptions.enableSchemaHooks = DatabaseOptions.enableSchemaHooks.default; + } else if (typeof databaseOptions.enableSchemaHooks !== 'boolean') { + throw `databaseOptions.enableSchemaHooks must be a boolean`; + } + if (databaseOptions.schemaCacheTtl === undefined) { + databaseOptions.schemaCacheTtl = DatabaseOptions.schemaCacheTtl.default; + } else if (typeof databaseOptions.schemaCacheTtl !== 'number') { + throw `databaseOptions.schemaCacheTtl must be a number`; + } + } + + static validateRateLimit(rateLimit) { + if (!rateLimit) { + return; + } + if ( + Object.prototype.toString.call(rateLimit) !== '[object Object]' && + !Array.isArray(rateLimit) + ) { + throw `rateLimit must be an array or object`; + } + const options = Array.isArray(rateLimit) ? rateLimit : [rateLimit]; + for (const option of options) { + if (Object.prototype.toString.call(option) !== '[object Object]') { + throw `rateLimit must be an array of objects`; + } + if (option.requestPath == null) { + throw `rateLimit.requestPath must be defined`; + } + if (typeof option.requestPath !== 'string') { + throw `rateLimit.requestPath must be a string`; + } + if (option.requestTimeWindow == null) { + throw `rateLimit.requestTimeWindow must be defined`; + } + if (typeof option.requestTimeWindow !== 'number') { + throw `rateLimit.requestTimeWindow must be a number`; + } + if (option.includeInternalRequests && typeof option.includeInternalRequests !== 'boolean') { + throw `rateLimit.includeInternalRequests must be a boolean`; + } + if (option.requestCount == null) { + throw `rateLimit.requestCount must be defined`; + } + if (typeof option.requestCount !== 'number') { + throw `rateLimit.requestCount must be a number`; + } + if (option.errorResponseMessage && typeof option.errorResponseMessage !== 'string') { + throw `rateLimit.errorResponseMessage must be a string`; + } + const options = Object.keys(ParseServer.RateLimitZone); + if (option.zone && !options.includes(option.zone)) { + const formatter = new Intl.ListFormat('en', { style: 'short', type: 'disjunction' }); + throw `rateLimit.zone must be one of ${formatter.format(options)}`; + } + } + } + generateEmailVerifyTokenExpiresAt() { if (!this.verifyUserEmails || !this.emailVerifyTokenValidityDuration) { return undefined; @@ -514,6 +652,16 @@ export class Config { return new Date(now.getTime() + this.sessionLength * 1000); } + unregisterRateLimiters() { + let i = this.rateLimits?.length; + while (i--) { + const limit = this.rateLimits[i]; + if (limit.cloud) { + this.rateLimits.splice(i, 1); + } + } + } + get invalidLinkURL() { return this.customPages.invalidLink || `${this.publicServerURL}/apps/invalid_link.html`; } diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 89461750ce..c5c3d1ab05 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -68,14 +68,22 @@ const specialMasterQueryKeys = [ '_password_history', ]; -const validateQuery = (query: any, isMaster: boolean, update: boolean): void => { +const validateQuery = ( + query: any, + isMaster: boolean, + isMaintenance: boolean, + update: boolean +): void => { + if (isMaintenance) { + isMaster = true; + } if (query.ACL) { throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Cannot query on ACL.'); } if (query.$or) { if (query.$or instanceof Array) { - query.$or.forEach(value => validateQuery(value, isMaster, update)); + query.$or.forEach(value => validateQuery(value, isMaster, isMaintenance, update)); } else { throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Bad $or format - use an array value.'); } @@ -83,7 +91,7 @@ const validateQuery = (query: any, isMaster: boolean, update: boolean): void => if (query.$and) { if (query.$and instanceof Array) { - query.$and.forEach(value => validateQuery(value, isMaster, update)); + query.$and.forEach(value => validateQuery(value, isMaster, isMaintenance, update)); } else { throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Bad $and format - use an array value.'); } @@ -91,7 +99,7 @@ const validateQuery = (query: any, isMaster: boolean, update: boolean): void => if (query.$nor) { if (query.$nor instanceof Array && query.$nor.length > 0) { - query.$nor.forEach(value => validateQuery(value, isMaster, update)); + query.$nor.forEach(value => validateQuery(value, isMaster, isMaintenance, update)); } else { throw new Parse.Error( Parse.Error.INVALID_QUERY, @@ -124,6 +132,7 @@ const validateQuery = (query: any, isMaster: boolean, update: boolean): void => // Filters out any data that shouldn't be on this REST-formatted object. const filterSensitiveData = ( isMaster: boolean, + isMaintenance: boolean, aclGroup: any[], auth: any, operation: any, @@ -195,6 +204,15 @@ const filterSensitiveData = ( } const isUserClass = className === '_User'; + if (isUserClass) { + object.password = object._hashed_password; + delete object._hashed_password; + delete object.sessionToken; + } + + if (isMaintenance) { + return object; + } /* special treat for the user class: don't filter protectedFields if currently loggedin user is the retrieved user */ @@ -202,28 +220,17 @@ const filterSensitiveData = ( protectedFields && protectedFields.forEach(k => delete object[k]); // fields not requested by client (excluded), - //but were needed to apply protecttedFields - perms.protectedFields && - perms.protectedFields.temporaryKeys && - perms.protectedFields.temporaryKeys.forEach(k => delete object[k]); - } - - if (isUserClass) { - object.password = object._hashed_password; - delete object._hashed_password; - delete object.sessionToken; + // but were needed to apply protectedFields + perms?.protectedFields?.temporaryKeys?.forEach(k => delete object[k]); } - if (isMaster) { - return object; - } for (const key in object) { if (key.charAt(0) === '_') { delete object[key]; } } - if (!isUserClass) { + if (!isUserClass || isMaster) { return object; } @@ -272,6 +279,9 @@ const flattenUpdateOperatorsForCreate = object => { } object[key] = object[key].amount; break; + case 'SetOnInsert': + object[key] = object[key].amount; + break; case 'Add': if (!(object[key].objects instanceof Array)) { throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array'); @@ -358,6 +368,22 @@ const relationSchema = { fields: { relatedId: { type: 'String' }, owningId: { type: 'String' } }, }; +const convertEmailToLowercase = (object, className, options) => { + if (className === '_User' && options.convertEmailToLowercase) { + if (typeof object['email'] === 'string') { + object['email'] = object['email'].toLowerCase(); + } + } +}; + +const convertUsernameToLowercase = (object, className, options) => { + if (className === '_User' && options.convertUsernameToLowercase) { + if (typeof object['username'] === 'string') { + object['username'] = object['username'].toLowerCase(); + } + } +}; + class DatabaseController { adapter: StorageAdapter; schemaCache: any; @@ -439,7 +465,8 @@ class DatabaseController { className: string, object: any, query: any, - runOptions: QueryOptions + runOptions: QueryOptions, + maintenance: boolean ): Promise { let schema; const acl = runOptions.acl; @@ -454,7 +481,7 @@ class DatabaseController { return this.canAddField(schema, className, object, aclGroup, runOptions); }) .then(() => { - return schema.validateObject(className, object, query); + return schema.validateObject(className, object, query, maintenance); }); } @@ -467,6 +494,11 @@ class DatabaseController { validateOnly: boolean = false, validSchemaController: SchemaController.SchemaController ): Promise { + try { + Utils.checkProhibitedKeywords(this.options, update); + } catch (error) { + return Promise.reject(new Parse.Error(Parse.Error.INVALID_KEY_NAME, error)); + } const originalQuery = query; const originalUpdate = update; // Make a copy of the object, so we don't mutate the incoming data. @@ -512,7 +544,7 @@ class DatabaseController { if (acl) { query = addWriteACL(query, acl); } - validateQuery(query, isMaster, true); + validateQuery(query, isMaster, false, true); return schemaController .getOneSchema(className, true) .catch(error => { @@ -557,6 +589,8 @@ class DatabaseController { } } update = transformObjectACL(update); + convertEmailToLowercase(update, className, this.options); + convertUsernameToLowercase(update, className, this.options); transformAuthData(className, update, schema); if (validateOnly) { return this.adapter.find(className, schema, query, {}).then(result => { @@ -758,7 +792,7 @@ class DatabaseController { if (acl) { query = addWriteACL(query, acl); } - validateQuery(query, isMaster, false); + validateQuery(query, isMaster, false, false); return schemaController .getOneSchema(className) .catch(error => { @@ -797,10 +831,17 @@ class DatabaseController { validateOnly: boolean = false, validSchemaController: SchemaController.SchemaController ): Promise { + try { + Utils.checkProhibitedKeywords(this.options, object); + } catch (error) { + return Promise.reject(new Parse.Error(Parse.Error.INVALID_KEY_NAME, error)); + } // Make a copy of the object, so we don't mutate the incoming data. const originalObject = object; object = transformObjectACL(object); + convertEmailToLowercase(object, className, this.options); + convertUsernameToLowercase(object, className, this.options); object.createdAt = { iso: object.createdAt, __type: 'Date' }; object.updatedAt = { iso: object.updatedAt, __type: 'Date' }; @@ -1147,11 +1188,13 @@ class DatabaseController { hint, caseInsensitive = false, explain, + comment, }: any = {}, auth: any = {}, validSchemaController: SchemaController.SchemaController ): Promise { - const isMaster = acl === undefined; + const isMaintenance = auth.isMaintenance; + const isMaster = acl === undefined || isMaintenance; const aclGroup = acl || []; op = op || (typeof query.objectId == 'string' && Object.keys(query).length === 1 ? 'get' : 'find'); @@ -1193,8 +1236,9 @@ class DatabaseController { keys, readPreference, hint, - caseInsensitive, + caseInsensitive: this.options.enableCollationCaseComparison ? false : caseInsensitive, explain, + comment, }; Object.keys(sort).forEach(fieldName => { if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { @@ -1253,7 +1297,7 @@ class DatabaseController { query = addReadACL(query, aclGroup); } } - validateQuery(query, isMaster, false); + validateQuery(query, isMaster, isMaintenance, false); if (count) { if (!classExists) { return 0; @@ -1264,7 +1308,8 @@ class DatabaseController { query, readPreference, undefined, - hint + hint, + comment ); } } else if (distinct) { @@ -1283,7 +1328,8 @@ class DatabaseController { pipeline, readPreference, hint, - explain + explain, + comment ); } } else if (explain) { @@ -1296,6 +1342,7 @@ class DatabaseController { object = untransformObjectACL(object); return filterSensitiveData( isMaster, + isMaintenance, aclGroup, auth, op, @@ -1696,31 +1743,27 @@ class DatabaseController { throw error; }); - await this.adapter - .ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true) - .catch(error => { - logger.warn('Unable to create case insensitive username index: ', error); - throw error; - }); - await this.adapter - .ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true) - .catch(error => { - logger.warn('Unable to create case insensitive username index: ', error); - throw error; - }); + if (!this.options.enableCollationCaseComparison) { + await this.adapter + .ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true) + .catch(error => { + logger.warn('Unable to create case insensitive username index: ', error); + throw error; + }); + + await this.adapter + .ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true) + .catch(error => { + logger.warn('Unable to create case insensitive email index: ', error); + throw error; + }); + } await this.adapter.ensureUniqueness('_User', requiredUserFields, ['email']).catch(error => { logger.warn('Unable to ensure uniqueness for user email addresses: ', error); throw error; }); - await this.adapter - .ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true) - .catch(error => { - logger.warn('Unable to create case insensitive email index: ', error); - throw error; - }); - await this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name']).catch(error => { logger.warn('Unable to ensure uniqueness for role name: ', error); throw error; @@ -1803,7 +1846,7 @@ class DatabaseController { keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op && - ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1 + ['Add', 'AddUnique', 'Remove', 'Increment', 'SetOnInsert'].indexOf(keyUpdate.__op) > -1 ) { // only valid ops that produce an actionable result // the op may have happened on a keypath @@ -1813,8 +1856,8 @@ class DatabaseController { return Promise.resolve(response); } - static _validateQuery: (any, boolean, boolean) => void; - static filterSensitiveData: (boolean, any[], any, any, any, string, any[], any) => void; + static _validateQuery: (any, boolean, boolean, boolean) => void; + static filterSensitiveData: (boolean, boolean, any[], any, any, any, string, any[], any) => void; } module.exports = DatabaseController; diff --git a/src/Controllers/HooksController.js b/src/Controllers/HooksController.js index 9cc5f427e8..277104ef32 100644 --- a/src/Controllers/HooksController.js +++ b/src/Controllers/HooksController.js @@ -144,7 +144,7 @@ export class HooksController { if (aHook.functionName) { return this.getFunction(aHook.functionName).then(result => { if (result) { - throw new Parse.Error(143, `function name: ${aHook.functionName} already exits`); + throw new Parse.Error(143, `function name: ${aHook.functionName} already exists`); } else { return this.createOrUpdateHook(aHook); } diff --git a/src/Controllers/LiveQueryController.js b/src/Controllers/LiveQueryController.js index 9a5b6d0ef1..b3ee7fcf65 100644 --- a/src/Controllers/LiveQueryController.js +++ b/src/Controllers/LiveQueryController.js @@ -21,6 +21,10 @@ export class LiveQueryController { this.liveQueryPublisher = new ParseCloudCodePublisher(config); } + connect() { + return this.liveQueryPublisher.connect(); + } + onAfterSave( className: string, currentObject: any, diff --git a/src/Controllers/LoggerController.js b/src/Controllers/LoggerController.js index 8ee492cf4b..8466e5459a 100644 --- a/src/Controllers/LoggerController.js +++ b/src/Controllers/LoggerController.js @@ -16,7 +16,7 @@ export const LogOrder = { ASCENDING: 'asc', }; -const logLevels = ['error', 'warn', 'info', 'debug', 'verbose', 'silly']; +export const logLevels = ['error', 'warn', 'info', 'debug', 'verbose', 'silly']; export class LoggerController extends AdaptableController { constructor(adapter, appId, options = { logLevel: 'info' }) { diff --git a/src/Controllers/PushController.js b/src/Controllers/PushController.js index 1a5b9bf491..04fb5c4fd0 100644 --- a/src/Controllers/PushController.js +++ b/src/Controllers/PushController.js @@ -58,9 +58,16 @@ export class PushController { // Force filtering on only valid device tokens const updateWhere = applyDeviceTokenExists(where); - badgeUpdate = () => { + badgeUpdate = async () => { // Build a real RestQuery so we can use it in RestWrite - const restQuery = new RestQuery(config, master(config), '_Installation', updateWhere); + const restQuery = await RestQuery({ + method: RestQuery.Method.find, + config, + runBeforeFind: false, + auth: master(config), + className: '_Installation', + restWhere: updateWhere, + }); return restQuery.buildRestWhere().then(() => { const write = new RestWrite( config, diff --git a/src/Controllers/SchemaController.js b/src/Controllers/SchemaController.js index 179de37b6e..ad3699aaa5 100644 --- a/src/Controllers/SchemaController.js +++ b/src/Controllers/SchemaController.js @@ -682,6 +682,10 @@ const typeToString = (type: SchemaField | string): string => { } return `${type.type}`; }; +const ttl = { + date: Date.now(), + duration: undefined, +}; // Stores the entire schema of the app in a weird hybrid format somewhere between // the mongo format and the Parse format. Soon, this will all be Parse format. @@ -694,10 +698,11 @@ export default class SchemaController { constructor(databaseAdapter: StorageAdapter) { this._dbAdapter = databaseAdapter; + const config = Config.get(Parse.applicationId); this.schemaData = new SchemaData(SchemaCache.all(), this.protectedFields); - this.protectedFields = Config.get(Parse.applicationId).protectedFields; + this.protectedFields = config.protectedFields; - const customIds = Config.get(Parse.applicationId).allowCustomObjectId; + const customIds = config.allowCustomObjectId; const customIdRegEx = /^.{1,}$/u; // 1+ chars const autoIdRegEx = /^[a-zA-Z0-9]{1,}$/; @@ -709,6 +714,21 @@ export default class SchemaController { }); } + async reloadDataIfNeeded() { + if (this._dbAdapter.enableSchemaHooks) { + return; + } + const { date, duration } = ttl || {}; + if (!duration) { + return; + } + const now = Date.now(); + if (now - date > duration) { + ttl.date = now; + await this.reloadData({ clearCache: true }); + } + } + reloadData(options: LoadSchemaOptions = { clearCache: false }): Promise { if (this.reloadDataPromise && !options.clearCache) { return this.reloadDataPromise; @@ -729,10 +749,11 @@ export default class SchemaController { return this.reloadDataPromise; } - getAllClasses(options: LoadSchemaOptions = { clearCache: false }): Promise> { + async getAllClasses(options: LoadSchemaOptions = { clearCache: false }): Promise> { if (options.clearCache) { return this.setAllClasses(); } + await this.reloadDataIfNeeded(); const cached = SchemaCache.all(); if (cached && cached.length) { return Promise.resolve(cached); @@ -1071,14 +1092,19 @@ export default class SchemaController { className: string, fieldName: string, type: string | SchemaField, - isValidation?: boolean + isValidation?: boolean, + maintenance?: boolean ) { if (fieldName.indexOf('.') > 0) { // subdocument key (x.y) => ok if x is of type 'object' fieldName = fieldName.split('.')[0]; type = 'Object'; } - if (!fieldNameIsValid(fieldName, className)) { + let fieldNameToValidate = `${fieldName}`; + if (maintenance && fieldNameToValidate.charAt(0) === '_') { + fieldNameToValidate = fieldNameToValidate.substring(1); + } + if (!fieldNameIsValid(fieldNameToValidate, className)) { throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); } @@ -1228,7 +1254,7 @@ export default class SchemaController { // Validates an object provided in REST format. // Returns a promise that resolves to the new schema if this object is // valid. - async validateObject(className: string, object: any, query: any) { + async validateObject(className: string, object: any, query: any, maintenance: boolean) { let geocount = 0; const schema = await this.enforceClassExists(className); const promises = []; @@ -1258,7 +1284,7 @@ export default class SchemaController { // Every object has ACL implicitly. continue; } - promises.push(schema.enforceFieldExists(className, fieldName, expected, true)); + promises.push(schema.enforceFieldExists(className, fieldName, expected, true, maintenance)); } const results = await Promise.all(promises); const enforceFields = results.filter(result => !!result); @@ -1435,6 +1461,7 @@ export default class SchemaController { // Returns a promise for a new Schema. const load = (dbAdapter: StorageAdapter, options: any): Promise => { const schema = new SchemaController(dbAdapter); + ttl.duration = dbAdapter.schemaCacheTtl; return schema.reloadData(options).then(() => schema); }; diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index 62c165c1e2..0e8e18ae7d 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -32,23 +32,35 @@ export class UserController extends AdaptableController { } get shouldVerifyEmails() { - return this.options.verifyUserEmails; + return (this.config || this.options).verifyUserEmails; } - setEmailVerifyToken(user) { - if (this.shouldVerifyEmails) { - user._email_verify_token = randomString(25); + async setEmailVerifyToken(user, req, storage = {}) { + const shouldSendEmail = + this.shouldVerifyEmails === true || + (typeof this.shouldVerifyEmails === 'function' && + (await Promise.resolve(this.shouldVerifyEmails(req))) === true); + if (!shouldSendEmail) { + return false; + } + storage.sendVerificationEmail = true; + user._email_verify_token = randomString(25); + if ( + !storage.fieldsChangedByTrigger || + !storage.fieldsChangedByTrigger.includes('emailVerified') + ) { user.emailVerified = false; + } - if (this.config.emailVerifyTokenValidityDuration) { - user._email_verify_token_expires_at = Parse._encode( - this.config.generateEmailVerifyTokenExpiresAt() - ); - } + if (this.config.emailVerifyTokenValidityDuration) { + user._email_verify_token_expires_at = Parse._encode( + this.config.generateEmailVerifyTokenExpiresAt() + ); } + return true; } - verifyEmail(username, token) { + async verifyEmail(username, token) { if (!this.shouldVerifyEmails) { // Trying to verify email when not enabled // TODO: Better error here. @@ -69,20 +81,23 @@ export class UserController extends AdaptableController { updateFields._email_verify_token_expires_at = { __op: 'Delete' }; } - const masterAuth = Auth.master(this.config); - var findUserForEmailVerification = new RestQuery( - this.config, - Auth.master(this.config), - '_User', - { username: username } - ); + const maintenanceAuth = Auth.maintenance(this.config); + var findUserForEmailVerification = await RestQuery({ + method: RestQuery.Method.get, + config: this.config, + auth: maintenanceAuth, + className: '_User', + restWhere: { + username, + }, + }); return findUserForEmailVerification.execute().then(result => { if (result.results.length && result.results[0].emailVerified) { return Promise.resolve(result.results.length[0]); } else if (result.results.length) { query.objectId = result.results[0].objectId; } - return rest.update(this.config, masterAuth, '_User', query, updateFields); + return rest.update(this.config, maintenanceAuth, '_User', query, updateFields); }); } @@ -94,7 +109,8 @@ export class UserController extends AdaptableController { username: username, _perishable_token: token, }, - { limit: 1 } + { limit: 1 }, + Auth.maintenance(this.config) ) .then(results => { if (results.length != 1) { @@ -112,10 +128,7 @@ export class UserController extends AdaptableController { }); } - getUserIfNeeded(user) { - if (user.username && user.email) { - return Promise.resolve(user); - } + async getUserIfNeeded(user) { var where = {}; if (user.username) { where.username = user.username; @@ -124,36 +137,55 @@ export class UserController extends AdaptableController { where.email = user.email; } - var query = new RestQuery(this.config, Auth.master(this.config), '_User', where); - return query.execute().then(function (result) { - if (result.results.length != 1) { - throw undefined; - } - return result.results[0]; + var query = await RestQuery({ + method: RestQuery.Method.get, + config: this.config, + runBeforeFind: false, + auth: Auth.master(this.config), + className: '_User', + restWhere: where, }); + const result = await query.execute(); + if (result.results.length != 1) { + throw undefined; + } + return result.results[0]; } - sendVerificationEmail(user) { + async sendVerificationEmail(user, req) { if (!this.shouldVerifyEmails) { return; } const token = encodeURIComponent(user._email_verify_token); - // We may need to fetch the user in case of update email - this.getUserIfNeeded(user).then(user => { - const username = encodeURIComponent(user.username); - - const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config); - const options = { - appName: this.config.appName, - link: link, - user: inflate('_User', user), - }; - if (this.adapter.sendVerificationEmail) { - this.adapter.sendVerificationEmail(options); - } else { - this.adapter.sendMail(this.defaultVerificationEmail(options)); - } - }); + // We may need to fetch the user in case of update email; only use the `fetchedUser` + // from this point onwards; do not use the `user` as it may not contain all fields. + const fetchedUser = await this.getUserIfNeeded(user); + let shouldSendEmail = this.config.sendUserEmailVerification; + if (typeof shouldSendEmail === 'function') { + const response = await Promise.resolve( + this.config.sendUserEmailVerification({ + user: Parse.Object.fromJSON({ className: '_User', ...fetchedUser }), + master: req.auth?.isMaster, + }) + ); + shouldSendEmail = !!response; + } + if (!shouldSendEmail) { + return; + } + const username = encodeURIComponent(fetchedUser.username); + + const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config); + const options = { + appName: this.config.appName, + link: link, + user: inflate('_User', fetchedUser), + }; + if (this.adapter.sendVerificationEmail) { + this.adapter.sendVerificationEmail(options); + } else { + this.adapter.sendMail(this.defaultVerificationEmail(options)); + } } /** @@ -162,7 +194,7 @@ export class UserController extends AdaptableController { * @param user * @returns {*} */ - regenerateEmailVerifyToken(user) { + async regenerateEmailVerifyToken(user, master, installationId, ip) { const { _email_verify_token } = user; let { _email_verify_token_expires_at } = user; if (_email_verify_token_expires_at && _email_verify_token_expires_at.__type === 'Date') { @@ -174,21 +206,30 @@ export class UserController extends AdaptableController { _email_verify_token && new Date() < new Date(_email_verify_token_expires_at) ) { - return Promise.resolve(); + return Promise.resolve(true); + } + const shouldSend = await this.setEmailVerifyToken(user, { + object: Parse.User.fromJSON(Object.assign({ className: '_User' }, user)), + master, + installationId, + ip, + resendRequest: true + }); + if (!shouldSend) { + return; } - this.setEmailVerifyToken(user); return this.config.database.update('_User', { username: user.username }, user); } - resendVerificationEmail(username) { - return this.getUserIfNeeded({ username: username }).then(aUser => { - if (!aUser || aUser.emailVerified) { - throw undefined; - } - return this.regenerateEmailVerifyToken(aUser).then(() => { - this.sendVerificationEmail(aUser); - }); - }); + async resendVerificationEmail(username, req) { + const aUser = await this.getUserIfNeeded({ username: username }); + if (!aUser || aUser.emailVerified) { + throw undefined; + } + const generate = await this.regenerateEmailVerifyToken(aUser, req.auth?.isMaster, req.auth?.installationId, req.ip); + if (generate) { + this.sendVerificationEmail(aUser, req); + } } setPasswordResetToken(email) { @@ -228,7 +269,8 @@ export class UserController extends AdaptableController { { username: email, email: { $exists: false }, _perishable_token: { $exists: true } }, ], }, - { limit: 1 } + { limit: 1 }, + Auth.maintenance(this.config) ); if (results.length == 1) { let expiresDate = results[0]._perishable_token_expires_at; diff --git a/src/Deprecator/Deprecations.js b/src/Deprecator/Deprecations.js index 1c3d336be9..6fbd358fcc 100644 --- a/src/Deprecator/Deprecations.js +++ b/src/Deprecator/Deprecations.js @@ -16,12 +16,5 @@ * If there are no deprecations, this must return an empty array. */ module.exports = [ - { - optionKey: 'directAccess', - changeNewDefault: 'true', - solution: - "Additionally, the environment variable 'PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS' will be deprecated and renamed to 'PARSE_SERVER_DIRECT_ACCESS' in a future version; it is currently possible to use either one.", - }, - { optionKey: 'enforcePrivateUsers', changeNewDefault: 'true' }, - { optionKey: 'allowClientClassCreation', changeNewDefault: 'false' }, + { optionKey: 'encodeParseObjectInCloudFunction', changeNewDefault: 'true' }, ]; diff --git a/src/GraphQL/ParseGraphQLServer.js b/src/GraphQL/ParseGraphQLServer.js index 7ab03fc1be..00218e0cdb 100644 --- a/src/GraphQL/ParseGraphQLServer.js +++ b/src/GraphQL/ParseGraphQLServer.js @@ -1,8 +1,12 @@ import corsMiddleware from 'cors'; -import { createServer, renderGraphiQL } from '@graphql-yoga/node'; +import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js'; +import { ApolloServer } from '@apollo/server'; +import { expressMiddleware } from '@apollo/server/express4'; +import { ApolloServerPluginCacheControlDisabled } from '@apollo/server/plugin/disabled'; +import express from 'express'; import { execute, subscribe } from 'graphql'; import { SubscriptionServer } from 'subscriptions-transport-ws'; -import { handleParseErrors, handleParseHeaders } from '../middlewares'; +import { handleParseErrors, handleParseHeaders, handleParseSession } from '../middlewares'; import requiredParameter from '../requiredParameter'; import defaultLogger from '../logger'; import { ParseGraphQLSchema } from './ParseGraphQLSchema'; @@ -33,16 +37,13 @@ class ParseGraphQLServer { try { return { schema: await this.parseGraphQLSchema.load(), - context: ({ req: { info, config, auth } }) => ({ - info, - config, - auth, - }), - maskedErrors: false, - multipart: { - fileSize: this._transformMaxUploadSizeToBytes( - this.parseServer.config.maxUploadSize || '20mb' - ), + context: async ({ req, res }) => { + res.set('access-control-allow-origin', req.get('origin') || '*'); + return { + info: req.info, + config: req.config, + auth: req.auth, + }; }, }; } catch (e) { @@ -57,8 +58,21 @@ class ParseGraphQLServer { if (schemaRef === newSchemaRef && this._server) { return this._server; } - const options = await this._getGraphQLOptions(); - this._server = createServer(options); + const { schema, context } = await this._getGraphQLOptions(); + const apollo = new ApolloServer({ + csrfPrevention: { + // See https://www.apollographql.com/docs/router/configuration/csrf/ + // needed since we use graphql upload + requestHeaders: ['X-Parse-Application-Id'], + }, + introspection: true, + plugins: [ApolloServerPluginCacheControlDisabled()], + schema, + }); + await apollo.start(); + this._server = expressMiddleware(apollo, { + context, + }); return this._server; } @@ -79,13 +93,21 @@ class ParseGraphQLServer { if (!app || !app.use) { requiredParameter('You must provide an Express.js app instance!'); } - app.use(this.config.graphQLPath, corsMiddleware()); app.use(this.config.graphQLPath, handleParseHeaders); + app.use(this.config.graphQLPath, handleParseSession); app.use(this.config.graphQLPath, handleParseErrors); - app.use(this.config.graphQLPath, async (req, res) => { + app.use( + this.config.graphQLPath, + graphqlUploadExpress({ + maxFileSize: this._transformMaxUploadSizeToBytes( + this.parseServer.config.maxUploadSize || '20mb' + ), + }) + ); + app.use(this.config.graphQLPath, express.json(), async (req, res, next) => { const server = await this._getServer(); - return server(req, res); + return server(req, res, next); }); } @@ -93,20 +115,33 @@ class ParseGraphQLServer { if (!app || !app.get) { requiredParameter('You must provide an Express.js app instance!'); } + app.get( this.config.playgroundPath || requiredParameter('You must provide a config.playgroundPath to applyPlayground!'), (_req, res) => { res.setHeader('Content-Type', 'text/html'); res.write( - renderGraphiQL({ - endpoint: this.config.graphQLPath, - subscriptionEndpoint: this.config.subscriptionsPath, - headers: JSON.stringify({ - 'X-Parse-Application-Id': this.parseServer.config.appId, - 'X-Parse-Master-Key': this.parseServer.config.masterKey, - }), - }) + `
+ + ` ); res.end(); } diff --git a/src/GraphQL/loaders/defaultGraphQLTypes.js b/src/GraphQL/loaders/defaultGraphQLTypes.js index 6824f75ba6..a7dd523ba5 100644 --- a/src/GraphQL/loaders/defaultGraphQLTypes.js +++ b/src/GraphQL/loaders/defaultGraphQLTypes.js @@ -15,6 +15,7 @@ import { GraphQLUnionType, } from 'graphql'; import { toGlobalId } from 'graphql-relay'; +import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'; class TypeValidationError extends Error { constructor(value, type) { @@ -222,11 +223,6 @@ const DATE = new GraphQLScalarType({ }, }); -const GraphQLUpload = new GraphQLScalarType({ - name: 'Upload', - description: 'The Upload scalar type represents a file upload.', -}); - const BYTES = new GraphQLScalarType({ name: 'Bytes', description: diff --git a/src/GraphQL/loaders/filesMutations.js b/src/GraphQL/loaders/filesMutations.js index 1b6c26ab40..212aa0b337 100644 --- a/src/GraphQL/loaders/filesMutations.js +++ b/src/GraphQL/loaders/filesMutations.js @@ -1,33 +1,61 @@ import { GraphQLNonNull } from 'graphql'; +import { request } from 'http'; +import { getExtension } from 'mime'; import { mutationWithClientMutationId } from 'graphql-relay'; import Parse from 'parse/node'; import * as defaultGraphQLTypes from './defaultGraphQLTypes'; import logger from '../../logger'; +// Handle GraphQL file upload and proxy file upload to GraphQL server url specified in config; +// `createFile` is not directly called by Parse Server to leverage standard file upload mechanism const handleUpload = async (upload, config) => { - const data = Buffer.from(await upload.arrayBuffer()); - const fileName = upload.name; - const type = upload.type; - - if (!data || !data.length) { - throw new Parse.Error(Parse.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); - } - - if (fileName.length > 128) { - throw new Parse.Error(Parse.Error.INVALID_FILE_NAME, 'Filename too long.'); - } - - if (!fileName.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) { - throw new Parse.Error(Parse.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); - } - + const { createReadStream, filename, mimetype } = await upload; + const headers = { ...config.headers }; + delete headers['accept-encoding']; + delete headers['accept']; + delete headers['connection']; + delete headers['host']; + delete headers['content-length']; + const stream = createReadStream(); try { + const ext = getExtension(mimetype); + const fullFileName = filename.endsWith(`.${ext}`) ? filename : `${filename}.${ext}`; + const serverUrl = new URL(config.serverURL); + const fileInfo = await new Promise((resolve, reject) => { + const req = request( + { + hostname: serverUrl.hostname, + port: serverUrl.port, + path: `${serverUrl.pathname}/files/${fullFileName}`, + method: 'POST', + headers, + }, + res => { + let data = ''; + res.on('data', chunk => { + data += chunk; + }); + res.on('end', () => { + try { + resolve(JSON.parse(data)); + } catch (e) { + reject(new Parse.Error(Parse.error, data)); + } + }); + } + ); + stream.pipe(req); + stream.on('end', () => { + req.end(); + }); + }); return { - fileInfo: await config.filesController.createFile(config, fileName, data, type), + fileInfo, }; } catch (e) { + stream.destroy(); logger.error('Error creating a file: ', e); - throw new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `Could not store file: ${fileName}.`); + throw new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `Could not store file: ${filename}.`); } }; diff --git a/src/GraphQL/loaders/parseClassMutations.js b/src/GraphQL/loaders/parseClassMutations.js index 41d7c09dde..aa15f70505 100644 --- a/src/GraphQL/loaders/parseClassMutations.js +++ b/src/GraphQL/loaders/parseClassMutations.js @@ -82,6 +82,7 @@ const load = function (parseGraphQLSchema, parseClass, parseClassConfig: ?ParseG const parseFields = await transformTypes('create', fields, { className, parseGraphQLSchema, + originalFields: args.fields, req: { config, auth, info }, }); @@ -190,6 +191,7 @@ const load = function (parseGraphQLSchema, parseClass, parseClassConfig: ?ParseG const parseFields = await transformTypes('update', fields, { className, parseGraphQLSchema, + originalFields: args.fields, req: { config, auth, info }, }); diff --git a/src/GraphQL/loaders/parseClassTypes.js b/src/GraphQL/loaders/parseClassTypes.js index df4ed791ea..4f54fe2b2e 100644 --- a/src/GraphQL/loaders/parseClassTypes.js +++ b/src/GraphQL/loaders/parseClassTypes.js @@ -1,3 +1,4 @@ +/* eslint-disable indent */ import { GraphQLID, GraphQLObjectType, @@ -140,11 +141,7 @@ const load = (parseGraphQLSchema, parseClass, parseClassConfig: ?ParseGraphQLCla ...fields, [field]: { description: `This is the object ${field}.`, - type: - (className === '_User' && (field === 'username' || field === 'password')) || - parseClass.fields[field].required - ? new GraphQLNonNull(type) - : type, + type: parseClass.fields[field].required ? new GraphQLNonNull(type) : type, }, }; } else { @@ -352,6 +349,14 @@ const load = (parseGraphQLSchema, parseClass, parseClassConfig: ?ParseGraphQLCla const parseObjectFields = { id: globalIdField(className, obj => obj.objectId), ...defaultGraphQLTypes.PARSE_OBJECT_FIELDS, + ...(className === '_User' + ? { + authDataResponse: { + description: `auth provider response when triggered on signUp/logIn.`, + type: defaultGraphQLTypes.OBJECT, + }, + } + : {}), }; const outputFields = () => { return classOutputFields.reduce((fields, field) => { diff --git a/src/GraphQL/loaders/usersMutations.js b/src/GraphQL/loaders/usersMutations.js index c38905cd90..58236cdbd4 100644 --- a/src/GraphQL/loaders/usersMutations.js +++ b/src/GraphQL/loaders/usersMutations.js @@ -38,10 +38,11 @@ const load = parseGraphQLSchema => { const parseFields = await transformTypes('create', fields, { className: '_User', parseGraphQLSchema, + originalFields: args.fields, req: { config, auth, info }, }); - const { sessionToken, objectId } = await objectsMutations.createObject( + const { sessionToken, objectId, authDataResponse } = await objectsMutations.createObject( '_User', parseFields, config, @@ -50,9 +51,15 @@ const load = parseGraphQLSchema => { ); context.info.sessionToken = sessionToken; - + const viewer = await getUserFromSessionToken( + context, + mutationInfo, + 'viewer.user.', + objectId + ); + if (authDataResponse && viewer.user) viewer.user.authDataResponse = authDataResponse; return { - viewer: await getUserFromSessionToken(context, mutationInfo, 'viewer.user.', objectId), + viewer, }; } catch (e) { parseGraphQLSchema.handleError(e); @@ -108,10 +115,11 @@ const load = parseGraphQLSchema => { const parseFields = await transformTypes('create', fields, { className: '_User', parseGraphQLSchema, + originalFields: args.fields, req: { config, auth, info }, }); - const { sessionToken, objectId } = await objectsMutations.createObject( + const { sessionToken, objectId, authDataResponse } = await objectsMutations.createObject( '_User', { ...parseFields, authData }, config, @@ -120,9 +128,15 @@ const load = parseGraphQLSchema => { ); context.info.sessionToken = sessionToken; - + const viewer = await getUserFromSessionToken( + context, + mutationInfo, + 'viewer.user.', + objectId + ); + if (authDataResponse && viewer.user) viewer.user.authDataResponse = authDataResponse; return { - viewer: await getUserFromSessionToken(context, mutationInfo, 'viewer.user.', objectId), + viewer, }; } catch (e) { parseGraphQLSchema.handleError(e); @@ -146,6 +160,10 @@ const load = parseGraphQLSchema => { description: 'This is the password used to log in the user.', type: new GraphQLNonNull(GraphQLString), }, + authData: { + description: 'Auth data payload, needed if some required auth adapters are configured.', + type: OBJECT, + }, }, outputFields: { viewer: { @@ -155,14 +173,15 @@ const load = parseGraphQLSchema => { }, mutateAndGetPayload: async (args, context, mutationInfo) => { try { - const { username, password } = deepcopy(args); + const { username, password, authData } = deepcopy(args); const { config, auth, info } = context; - const { sessionToken, objectId } = ( + const { sessionToken, objectId, authDataResponse } = ( await usersRouter.handleLogIn({ body: { username, password, + authData, }, query: {}, config, @@ -173,8 +192,15 @@ const load = parseGraphQLSchema => { context.info.sessionToken = sessionToken; + const viewer = await getUserFromSessionToken( + context, + mutationInfo, + 'viewer.user.', + objectId + ); + if (authDataResponse && viewer.user) viewer.user.authDataResponse = authDataResponse; return { - viewer: await getUserFromSessionToken(context, mutationInfo, 'viewer.user.', objectId), + viewer, }; } catch (e) { parseGraphQLSchema.handleError(e); @@ -355,6 +381,57 @@ const load = parseGraphQLSchema => { true, true ); + + const challengeMutation = mutationWithClientMutationId({ + name: 'Challenge', + description: + 'The challenge mutation can be used to initiate an authentication challenge when an auth adapter needs it.', + inputFields: { + username: { + description: 'This is the username used to log in the user.', + type: GraphQLString, + }, + password: { + description: 'This is the password used to log in the user.', + type: GraphQLString, + }, + authData: { + description: + 'Auth data allow to preidentify the user if the auth adapter needs preidentification.', + type: OBJECT, + }, + challengeData: { + description: + 'Challenge data payload, can be used to post data to auth providers to auth providers if they need data for the response.', + type: OBJECT, + }, + }, + outputFields: { + challengeData: { + description: 'Challenge response from configured auth adapters.', + type: OBJECT, + }, + }, + mutateAndGetPayload: async (input, context) => { + try { + const { config, auth, info } = context; + + const { response } = await usersRouter.handleChallenge({ + body: input, + config, + auth, + info, + }); + return response; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + }, + }); + + parseGraphQLSchema.addGraphQLType(challengeMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(challengeMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('challenge', challengeMutation, true, true); }; export { load }; diff --git a/src/GraphQL/parseGraphQLUtils.js b/src/GraphQL/parseGraphQLUtils.js index 19b91f681b..2f4998c55c 100644 --- a/src/GraphQL/parseGraphQLUtils.js +++ b/src/GraphQL/parseGraphQLUtils.js @@ -1,5 +1,5 @@ import Parse from 'parse/node'; -import { GraphQLYogaError } from '@graphql-yoga/node'; +import { GraphQLError } from 'graphql'; export function enforceMasterKeyAccess(auth) { if (!auth.isMaster) { @@ -16,7 +16,7 @@ export function toGraphQLError(error) { code = Parse.Error.INTERNAL_SERVER_ERROR; message = 'Internal server error'; } - return new GraphQLYogaError(message, { code }); + return new GraphQLError(message, { extensions: { code } }); } export const extractKeysAndInclude = selectedFields => { diff --git a/src/GraphQL/transformers/mutation.js b/src/GraphQL/transformers/mutation.js index 5b72d6f05d..17dd6a8d4b 100644 --- a/src/GraphQL/transformers/mutation.js +++ b/src/GraphQL/transformers/mutation.js @@ -7,7 +7,7 @@ import * as objectsMutations from '../helpers/objectsMutations'; const transformTypes = async ( inputType: 'create' | 'update', fields, - { className, parseGraphQLSchema, req } + { className, parseGraphQLSchema, req, originalFields } ) => { const { classGraphQLCreateType, @@ -44,13 +44,16 @@ const transformTypes = async ( fields[field] = transformers.polygon(fields[field]); break; case inputTypeField.type === defaultGraphQLTypes.FILE_INPUT: - fields[field] = await transformers.file(fields[field], req); + // Use `originalFields` to handle file upload since fields are a deepcopy and do not + // keep the file object + fields[field] = await transformers.file(originalFields[field], req); break; case parseClass.fields[field].type === 'Relation': fields[field] = await transformers.relation( parseClass.fields[field].targetClass, field, fields[field], + originalFields[field], parseGraphQLSchema, req ); @@ -64,6 +67,7 @@ const transformTypes = async ( parseClass.fields[field].targetClass, field, fields[field], + originalFields[field], parseGraphQLSchema, req ); @@ -135,7 +139,14 @@ const transformers = { } return parseACL; }, - relation: async (targetClass, field, value, parseGraphQLSchema, { config, auth, info }) => { + relation: async ( + targetClass, + field, + value, + originalValue, + parseGraphQLSchema, + { config, auth, info } + ) => { if (Object.keys(value).length === 0) throw new Parse.Error( Parse.Error.INVALID_POINTER, @@ -151,9 +162,10 @@ const transformers = { if (value.createAndAdd) { nestedObjectsToAdd = ( await Promise.all( - value.createAndAdd.map(async input => { + value.createAndAdd.map(async (input, i) => { const parseFields = await transformTypes('create', input, { className: targetClass, + originalFields: originalValue.createAndAdd[i], parseGraphQLSchema, req: { config, auth, info }, }); @@ -204,7 +216,14 @@ const transformers = { } return op; }, - pointer: async (targetClass, field, value, parseGraphQLSchema, { config, auth, info }) => { + pointer: async ( + targetClass, + field, + value, + originalValue, + parseGraphQLSchema, + { config, auth, info } + ) => { if (Object.keys(value).length > 1 || Object.keys(value).length === 0) throw new Parse.Error( Parse.Error.INVALID_POINTER, @@ -216,6 +235,7 @@ const transformers = { const parseFields = await transformTypes('create', value.createAndLink, { className: targetClass, parseGraphQLSchema, + originalFields: originalValue.createAndLink, req: { config, auth, info }, }); nestedObjectToAdd = await objectsMutations.createObject( diff --git a/src/LiveQuery/Client.js b/src/LiveQuery/Client.js index 56d1baedcd..0ce629bd4e 100644 --- a/src/LiveQuery/Client.js +++ b/src/LiveQuery/Client.js @@ -98,13 +98,13 @@ class Client { response['requestId'] = subscriptionId; } if (typeof parseObjectJSON !== 'undefined') { - let fields; + let keys; if (this.subscriptionInfos.has(subscriptionId)) { - fields = this.subscriptionInfos.get(subscriptionId).fields; + keys = this.subscriptionInfos.get(subscriptionId).keys; } - response['object'] = this._toJSONWithFields(parseObjectJSON, fields); + response['object'] = this._toJSONWithFields(parseObjectJSON, keys); if (parseOriginalObjectJSON) { - response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, fields); + response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, keys); } } Client.pushResponse(this.parseWebSocket, JSON.stringify(response)); diff --git a/src/LiveQuery/ParseCloudCodePublisher.js b/src/LiveQuery/ParseCloudCodePublisher.js index 3ecd740e12..0e0dce1417 100644 --- a/src/LiveQuery/ParseCloudCodePublisher.js +++ b/src/LiveQuery/ParseCloudCodePublisher.js @@ -11,6 +11,15 @@ class ParseCloudCodePublisher { this.parsePublisher = ParsePubSub.createPublisher(config); } + async connect() { + if (typeof this.parsePublisher.connect === 'function') { + if (this.parsePublisher.isOpen) { + return; + } + return Promise.resolve(this.parsePublisher.connect()); + } + } + onCloudCodeAfterSave(request: any): void { this._onCloudCodeMessage(Parse.applicationId + 'afterSave', request); } diff --git a/src/LiveQuery/ParseLiveQueryServer.js b/src/LiveQuery/ParseLiveQueryServer.js index 02c6ad30a1..004ef46810 100644 --- a/src/LiveQuery/ParseLiveQueryServer.js +++ b/src/LiveQuery/ParseLiveQueryServer.js @@ -19,9 +19,11 @@ import { } from '../triggers'; import { getAuthForSessionToken, Auth } from '../Auth'; import { getCacheController, getDatabaseController } from '../Controllers'; -import LRU from 'lru-cache'; +import { LRUCache as LRU } from 'lru-cache'; import UserRouter from '../Routers/UsersRouter'; import DatabaseController from '../Controllers/DatabaseController'; +import { isDeepStrictEqual } from 'util'; +import deepcopy from 'deepcopy'; class ParseLiveQueryServer { clients: Map; @@ -73,15 +75,40 @@ class ParseLiveQueryServer { parseWebsocket => this._onConnect(parseWebsocket), config ); - - // Initialize subscriber this.subscriber = ParsePubSub.createSubscriber(config); - this.subscriber.subscribe(Parse.applicationId + 'afterSave'); - this.subscriber.subscribe(Parse.applicationId + 'afterDelete'); - this.subscriber.subscribe(Parse.applicationId + 'clearCache'); - // Register message handler for subscriber. When publisher get messages, it will publish message - // to the subscribers and the handler will be called. - this.subscriber.on('message', (channel, messageStr) => { + if (!this.subscriber.connect) { + this.connect(); + } + } + + async connect() { + if (this.subscriber.isOpen) { + return; + } + if (typeof this.subscriber.connect === 'function') { + await Promise.resolve(this.subscriber.connect()); + } else { + this.subscriber.isOpen = true; + } + this._createSubscribers(); + } + + async shutdown() { + if (this.subscriber.isOpen) { + await Promise.all([ + ...[...this.clients.values()].map(client => client.parseWebSocket.ws.close()), + this.parseWebSocketServer.close(), + ...Array.from(this.subscriber.subscriptions.keys()).map(key => + this.subscriber.unsubscribe(key) + ), + this.subscriber.close?.(), + ]); + } + this.subscriber.isOpen = false; + } + + _createSubscribers() { + const messageRecieved = (channel, messageStr) => { logger.verbose('Subscribe message %j', messageStr); let message; try { @@ -102,7 +129,12 @@ class ParseLiveQueryServer { } else { logger.error('Get message %s from unknown channel %j', message, channel); } - }); + }; + this.subscriber.on('message', (channel, messageStr) => messageRecieved(channel, messageStr)); + for (const field of ['afterSave', 'afterDelete', 'clearCache']) { + const channel = `${Parse.applicationId}${field}`; + this.subscriber.subscribe(channel, messageStr => messageRecieved(channel, messageStr)); + } } // Message is the JSON object from publisher. Message.currentParseObject is the ParseObject JSON after changes. @@ -314,6 +346,10 @@ class ParseLiveQueryServer { } else { return null; } + const watchFieldsChanged = this._checkWatchFields(client, requestId, message); + if (!watchFieldsChanged && (type === 'update' || type === 'create')) { + return; + } res = { event: type, sessionToken: client.sessionToken, @@ -475,7 +511,7 @@ class ParseLiveQueryServer { if (!parseObject) { return false; } - return matchesQuery(parseObject, subscription.query); + return matchesQuery(deepcopy(parseObject), subscription.query); } async _clearCachedRoles(userId: string) { @@ -496,7 +532,7 @@ class ParseLiveQueryServer { ]); auth1.auth?.clearRoleCache(sessionToken); auth2.auth?.clearRoleCache(sessionToken); - this.authCache.del(sessionToken); + this.authCache.delete(sessionToken); }) ); } catch (e) { @@ -526,7 +562,7 @@ class ParseLiveQueryServer { result.error = error; this.authCache.set(sessionToken, Promise.resolve(result), this.config.cacheTimeout); } else { - this.authCache.del(sessionToken); + this.authCache.delete(sessionToken); } return result; }); @@ -610,6 +646,7 @@ class ParseLiveQueryServer { } return DatabaseController.filterSensitiveData( client.hasMasterKey, + false, aclGroup, clientAuth, op, @@ -691,6 +728,17 @@ class ParseLiveQueryServer { return auth; } + _checkWatchFields(client: any, requestId: any, message: any) { + const subscriptionInfo = client.getSubscriptionInfo(requestId); + const watch = subscriptionInfo?.watch; + if (!watch) { + return true; + } + const object = message.currentParseObject; + const original = message.originalParseObject; + return watch.some(field => !isDeepStrictEqual(object.get(field), original?.get(field))); + } + async _matchesACL(acl: any, client: any, requestId: number): Promise { // Return true directly if ACL isn't present, ACL is public read, or client has master key if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) { @@ -818,9 +866,6 @@ class ParseLiveQueryServer { await runTrigger(trigger, `beforeSubscribe.${className}`, request, auth); const query = request.query.toJSON(); - if (query.keys) { - query.fields = query.keys.split(','); - } request.query = query; } @@ -869,8 +914,13 @@ class ParseLiveQueryServer { subscription: subscription, }; // Add selected fields, sessionToken and installationId for this subscription if necessary - if (request.query.fields) { - subscriptionInfo.fields = request.query.fields; + if (request.query.keys) { + subscriptionInfo.keys = Array.isArray(request.query.keys) + ? request.query.keys + : request.query.keys.split(','); + } + if (request.query.watch) { + subscriptionInfo.watch = request.query.watch; } if (request.sessionToken) { subscriptionInfo.sessionToken = request.sessionToken; diff --git a/src/LiveQuery/QueryTools.js b/src/LiveQuery/QueryTools.js index 50d8d3394a..1607278f46 100644 --- a/src/LiveQuery/QueryTools.js +++ b/src/LiveQuery/QueryTools.js @@ -247,6 +247,11 @@ function matchesKeyConstraints(object, key, constraints) { return false; } break; + case '$eq': + if (!equalObjects(object[key], compareTo)) { + return false; + } + break; case '$ne': if (equalObjects(object[key], compareTo)) { return false; diff --git a/src/LiveQuery/RequestSchema.js b/src/LiveQuery/RequestSchema.js index 14cb2f046b..6e0a0566b2 100644 --- a/src/LiveQuery/RequestSchema.js +++ b/src/LiveQuery/RequestSchema.js @@ -62,7 +62,15 @@ const subscribe = { where: { type: 'object', }, - fields: { + keys: { + type: 'array', + items: { + type: 'string', + }, + minItems: 1, + uniqueItems: true, + }, + watch: { type: 'array', items: { type: 'string', @@ -100,7 +108,15 @@ const update = { where: { type: 'object', }, - fields: { + keys: { + type: 'array', + items: { + type: 'string', + }, + minItems: 1, + uniqueItems: true, + }, + watch: { type: 'array', items: { type: 'string', diff --git a/src/LiveQuery/SessionTokenCache.js b/src/LiveQuery/SessionTokenCache.js index 13b84c7367..a7f52b65a0 100644 --- a/src/LiveQuery/SessionTokenCache.js +++ b/src/LiveQuery/SessionTokenCache.js @@ -1,5 +1,5 @@ import Parse from 'parse/node'; -import LRU from 'lru-cache'; +import { LRUCache as LRU } from 'lru-cache'; import logger from '../logger'; function userForSessionToken(sessionToken) { diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index d8e3f841dd..ee1137b7ea 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -4,7 +4,6 @@ This code has been generated by resources/buildConfigDefinitions.js Do not edit manually, but update Options/index.js */ var parsers = require('./parsers'); - module.exports.SchemaOptions = { afterMigration: { env: 'PARSE_SERVER_SCHEMA_AFTER_MIGRATION', @@ -58,9 +57,9 @@ module.exports.ParseServerOptions = { }, allowClientClassCreation: { env: 'PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION', - help: 'Enable (or disable) client class creation, defaults to true', + help: 'Enable (or disable) client class creation, defaults to false', action: parsers.booleanParser, - default: true, + default: false, }, allowCustomObjectId: { env: 'PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID', @@ -68,6 +67,13 @@ module.exports.ParseServerOptions = { action: parsers.booleanParser, default: false, }, + allowExpiredAuthDataToken: { + env: 'PARSE_SERVER_ALLOW_EXPIRED_AUTH_DATA_TOKEN', + help: + 'Allow a user to log in even if the 3rd party authentication token that was used to sign in to their account has expired. If this is set to `false`, then the token will be validated every time the user signs in to their account. This refers to the token that is stored in the `_User.authData` field. Defaults to `false`.', + action: parsers.booleanParser, + default: false, + }, allowHeaders: { env: 'PARSE_SERVER_ALLOW_HEADERS', help: 'Add headers to Access-Control-Allow-Headers', @@ -75,7 +81,9 @@ module.exports.ParseServerOptions = { }, allowOrigin: { env: 'PARSE_SERVER_ALLOW_ORIGIN', - help: 'Sets the origin to Access-Control-Allow-Origin', + help: + 'Sets origins for Access-Control-Allow-Origin. This can be a string for a single origin or an array of strings for multiple origins.', + action: parsers.arrayParser, }, analyticsAdapter: { env: 'PARSE_SERVER_ANALYTICS_ADAPTER', @@ -95,7 +103,6 @@ module.exports.ParseServerOptions = { env: 'PARSE_SERVER_AUTH_PROVIDERS', help: 'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication', - action: parsers.arrayParser, }, cacheAdapter: { env: 'PARSE_SERVER_CACHE_ADAPTER', @@ -132,6 +139,20 @@ module.exports.ParseServerOptions = { help: 'A collection prefix for the classes', default: '', }, + convertEmailToLowercase: { + env: 'PARSE_SERVER_CONVERT_EMAIL_TO_LOWERCASE', + help: + 'Optional. If set to `true`, the `email` property of a user is automatically converted to lowercase before being stored in the database. Consequently, queries must match the case as stored in the database, which would be lowercase in this scenario. If `false`, the `email` property is stored as set, without any case modifications. Default is `false`.', + action: parsers.booleanParser, + default: false, + }, + convertUsernameToLowercase: { + env: 'PARSE_SERVER_CONVERT_USERNAME_TO_LOWERCASE', + help: + 'Optional. If set to `true`, the `username` property of a user is automatically converted to lowercase before being stored in the database. Consequently, queries must match the case as stored in the database, which would be lowercase in this scenario. If `false`, the `username` property is stored as set, without any case modifications. Default is `false`.', + action: parsers.booleanParser, + default: false, + }, customPages: { env: 'PARSE_SERVER_CUSTOM_PAGES', help: 'custom pages for password validation and reset', @@ -166,7 +187,7 @@ module.exports.ParseServerOptions = { help: 'Set to `true` if Parse requests within the same Node.js environment as Parse Server should be routed to Parse Server directly instead of via the HTTP interface. Default is `false`.

If set to `false` then Parse requests within the same Node.js environment as Parse Server are executed as HTTP requests sent to Parse Server via the `serverURL`. For example, a `Parse.Query` in Cloud Code is calling Parse Server via a HTTP request. The server is essentially making a HTTP request to itself, unnecessarily using network resources such as network ports.

\u26A0\uFE0F In environments where multiple Parse Server instances run behind a load balancer and Parse requests within the current Node.js environment should be routed via the load balancer and distributed as HTTP requests among all instances via the `serverURL`, this should be set to `false`.', action: parsers.booleanParser, - default: false, + default: true, }, dotNetKey: { env: 'PARSE_SERVER_DOT_NET_KEY', @@ -196,12 +217,26 @@ module.exports.ParseServerOptions = { action: parsers.booleanParser, default: true, }, + enableCollationCaseComparison: { + env: 'PARSE_SERVER_ENABLE_COLLATION_CASE_COMPARISON', + help: + 'Optional. If set to `true`, the collation rule of case comparison for queries and indexes is enabled. Enable this option to run Parse Server with MongoDB Atlas Serverless or AWS Amazon DocumentDB. If `false`, the collation rule of case comparison is disabled. Default is `false`.', + action: parsers.booleanParser, + default: false, + }, enableExpressErrorHandler: { env: 'PARSE_SERVER_ENABLE_EXPRESS_ERROR_HANDLER', help: 'Enables the default express error handler for all errors', action: parsers.booleanParser, default: false, }, + encodeParseObjectInCloudFunction: { + env: 'PARSE_SERVER_ENCODE_PARSE_OBJECT_IN_CLOUD_FUNCTION', + help: + 'If set to `true`, a `Parse.Object` that is in the payload when calling a Cloud Function will be converted to an instance of `Parse.Object`. If `false`, the object will not be converted and instead be a plain JavaScript object, which contains the raw data of a `Parse.Object` but is not an actual instance of `Parse.Object`. Default is `false`.

\u2139\uFE0F The expected behavior would be that the object is converted to an instance of `Parse.Object`, so you would normally set this option to `true`. The default is `false` because this is a temporary option that has been introduced to avoid a breaking change when fixing a bug where JavaScript objects are not converted to actual instances of `Parse.Object`.', + action: parsers.booleanParser, + default: false, + }, encryptionKey: { env: 'PARSE_SERVER_ENCRYPTION_KEY', help: 'Key for encrypting your files', @@ -210,7 +245,7 @@ module.exports.ParseServerOptions = { env: 'PARSE_SERVER_ENFORCE_PRIVATE_USERS', help: 'Set to true if new users should be created without public read and write access.', action: parsers.booleanParser, - default: false, + default: true, }, expireInactiveSessions: { env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', @@ -219,6 +254,12 @@ module.exports.ParseServerOptions = { action: parsers.booleanParser, default: true, }, + extendSessionOnUse: { + env: 'PARSE_SERVER_EXTEND_SESSION_ON_USE', + help: 'Whether Parse Server should automatically extend a valid session by the sessionLength', + action: parsers.booleanParser, + default: false, + }, fileKey: { env: 'PARSE_SERVER_FILE_KEY', help: 'Key for your files', @@ -283,11 +324,30 @@ module.exports.ParseServerOptions = { env: 'PARSE_SERVER_LOG_LEVEL', help: 'Sets the level for logs', }, + logLevels: { + env: 'PARSE_SERVER_LOG_LEVELS', + help: '(Optional) Overrides the log levels used internally by Parse Server to log events.', + action: parsers.objectParser, + default: {}, + }, logsFolder: { env: 'PARSE_SERVER_LOGS_FOLDER', help: "Folder for the logs (defaults to './logs'); set to null to disable file based logging", default: './logs', }, + maintenanceKey: { + env: 'PARSE_SERVER_MAINTENANCE_KEY', + help: + '(Optional) The maintenance key is used for modifying internal and read-only fields of Parse Server.

\u26A0\uFE0F This key is not intended to be used as part of a regular operation of Parse Server. This key is intended to conduct out-of-band changes such as one-time migrations or data correction tasks. Internal fields are not officially documented and may change at any time without publication in release changelogs. We strongly advice not to rely on internal fields as part of your regular operation and to investigate the implications of any planned changes *directly in the source code* of your current version of Parse Server.', + required: true, + }, + maintenanceKeyIps: { + env: 'PARSE_SERVER_MAINTENANCE_KEY_IPS', + help: + "(Optional) Restricts the use of maintenance key permissions to a list of IP addresses or ranges.

This option accepts a list of single IP addresses, for example `['10.0.0.1', '10.0.0.2']`. You can also use CIDR notation to specify an IP address range, for example `['10.0.1.0/24']`.

Special scenarios:
- Setting an empty array `[]` means that the maintenance key cannot be used even in Parse Server Cloud Code. This value cannot be set via an environment variable as there is no way to pass an empty array to Parse Server via an environment variable.
- Setting `['0.0.0.0/0', '::0']` means to allow any IPv4 and IPv6 address to use the maintenance key and effectively disables the IP filter.

Considerations:
- IPv4 and IPv6 addresses are not compared against each other. Each IP version (IPv4 and IPv6) needs to be considered separately. For example, `['0.0.0.0/0']` allows any IPv4 address and blocks every IPv6 address. Conversely, `['::0']` allows any IPv6 address and blocks every IPv4 address.
- Keep in mind that the IP version in use depends on the network stack of the environment in which Parse Server runs. A local environment may use a different IP version than a remote environment. For example, it's possible that locally the value `['0.0.0.0/0']` allows the request IP because the environment is using IPv4, but when Parse Server is deployed remotely the request IP is blocked because the remote environment is using IPv6.
- When setting the option via an environment variable the notation is a comma-separated string, for example `\"0.0.0.0/0,::0\"`.
- IPv6 zone indices (`%` suffix) are not supported, for example `fe80::1%eth0`, `fe80::1%1` or `::1%lo`.

Defaults to `['127.0.0.1', '::1']` which means that only `localhost`, the server instance on which Parse Server runs, is allowed to use the maintenance key.", + action: parsers.arrayParser, + default: ['127.0.0.1', '::1'], + }, masterKey: { env: 'PARSE_SERVER_MASTER_KEY', help: 'Your Parse Master Key', @@ -295,9 +355,10 @@ module.exports.ParseServerOptions = { }, masterKeyIps: { env: 'PARSE_SERVER_MASTER_KEY_IPS', - help: 'Restrict masterKey to be used by only these ips, defaults to [] (allow all ips)', + help: + "(Optional) Restricts the use of master key permissions to a list of IP addresses or ranges.

This option accepts a list of single IP addresses, for example `['10.0.0.1', '10.0.0.2']`. You can also use CIDR notation to specify an IP address range, for example `['10.0.1.0/24']`.

Special scenarios:
- Setting an empty array `[]` means that the master key cannot be used even in Parse Server Cloud Code. This value cannot be set via an environment variable as there is no way to pass an empty array to Parse Server via an environment variable.
- Setting `['0.0.0.0/0', '::0']` means to allow any IPv4 and IPv6 address to use the master key and effectively disables the IP filter.

Considerations:
- IPv4 and IPv6 addresses are not compared against each other. Each IP version (IPv4 and IPv6) needs to be considered separately. For example, `['0.0.0.0/0']` allows any IPv4 address and blocks every IPv6 address. Conversely, `['::0']` allows any IPv6 address and blocks every IPv4 address.
- Keep in mind that the IP version in use depends on the network stack of the environment in which Parse Server runs. A local environment may use a different IP version than a remote environment. For example, it's possible that locally the value `['0.0.0.0/0']` allows the request IP because the environment is using IPv4, but when Parse Server is deployed remotely the request IP is blocked because the remote environment is using IPv6.
- When setting the option via an environment variable the notation is a comma-separated string, for example `\"0.0.0.0/0,::0\"`.
- IPv6 zone indices (`%` suffix) are not supported, for example `fe80::1%eth0`, `fe80::1%1` or `::1%lo`.

Defaults to `['127.0.0.1', '::1']` which means that only `localhost`, the server instance on which Parse Server runs, is allowed to use the master key.", action: parsers.arrayParser, - default: [], + default: ['127.0.0.1', '::1'], }, maxLimit: { env: 'PARSE_SERVER_MAX_LIMIT', @@ -378,6 +439,13 @@ module.exports.ParseServerOptions = { action: parsers.booleanParser, default: false, }, + preventSignupWithUnverifiedEmail: { + env: 'PARSE_SERVER_PREVENT_SIGNUP_WITH_UNVERIFIED_EMAIL', + help: + "If set to `true` it prevents a user from signing up if the email has not yet been verified and email verification is required. In that case the server responds to the sign-up with HTTP status 400 and a Parse Error 205 `EMAIL_NOT_FOUND`. If set to `false` the server responds with HTTP status 200, and client SDKs return an unauthenticated Parse User without session token. In that case subsequent requests fail until the user's email address is verified.

Default is `false`.
Requires option `verifyUserEmails: true`.", + action: parsers.booleanParser, + default: false, + }, protectedFields: { env: 'PARSE_SERVER_PROTECTED_FIELDS', help: 'Protected fields that should be treated with extra security when fetching details.', @@ -398,6 +466,13 @@ module.exports.ParseServerOptions = { 'Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications', action: parsers.objectParser, }, + rateLimit: { + env: 'PARSE_SERVER_RATE_LIMIT', + help: + "Options to limit repeated requests to Parse Server APIs. This can be used to protect sensitive endpoints such as `/requestPasswordReset` from brute-force attacks or Parse Server as a whole from denial-of-service (DoS) attacks.

\u2139\uFE0F Mind the following limitations:
- rate limits applied per IP address; this limits protection against distributed denial-of-service (DDoS) attacks where many requests are coming from various IP addresses
- if multiple Parse Server instances are behind a load balancer or ran in a cluster, each instance will calculate it's own request rates, independent from other instances; this limits the applicability of this feature when using a load balancer and another rate limiting solution that takes requests across all instances into account may be more suitable
- this feature provides basic protection against denial-of-service attacks, but a more sophisticated solution works earlier in the request flow and prevents a malicious requests to even reach a server instance; it's therefore recommended to implement a solution according to architecture and user case.", + action: parsers.arrayParser, + default: [], + }, readOnlyMasterKey: { env: 'PARSE_SERVER_READ_ONLY_MASTER_KEY', help: 'Read-only key, which has the same capabilities as MasterKey without writes', @@ -448,14 +523,16 @@ module.exports.ParseServerOptions = { action: parsers.objectParser, default: {}, }, + sendUserEmailVerification: { + env: 'PARSE_SERVER_SEND_USER_EMAIL_VERIFICATION', + help: + 'Set to `false` to prevent sending of verification email. Supports a function with a return value of `true` or `false` for conditional email sending.

Default is `true`.
', + default: true, + }, serverCloseComplete: { env: 'PARSE_SERVER_SERVER_CLOSE_COMPLETE', help: 'Callback when server has closed', }, - serverStartComplete: { - env: 'PARSE_SERVER_SERVER_START_COMPLETE', - help: 'Callback when server has started', - }, serverURL: { env: 'PARSE_SERVER_URL', help: 'URL to your parse server with http:// or https://.', @@ -477,6 +554,13 @@ module.exports.ParseServerOptions = { help: 'Starts the liveQuery server', action: parsers.booleanParser, }, + trustProxy: { + env: 'PARSE_SERVER_TRUST_PROXY', + help: + 'The trust proxy settings. It is important to understand the exact setup of the reverse proxy, since this setting will trust values provided in the Parse Server API request. See the express trust proxy settings documentation. Defaults to `false`.', + action: parsers.objectParser, + default: [], + }, userSensitiveFields: { env: 'PARSE_SERVER_USER_SENSITIVE_FIELDS', help: @@ -491,8 +575,7 @@ module.exports.ParseServerOptions = { verifyUserEmails: { env: 'PARSE_SERVER_VERIFY_USER_EMAILS', help: - 'Set to `true` to require users to verify their email address to complete the sign-up process.

Default is `false`.', - action: parsers.booleanParser, + 'Set to `true` to require users to verify their email address to complete the sign-up process. Supports a function with a return value of `true` or `false` for conditional verification.

Default is `false`.', default: false, }, webhookKey: { @@ -500,6 +583,62 @@ module.exports.ParseServerOptions = { help: 'Key sent with outgoing webhook calls', }, }; +module.exports.RateLimitOptions = { + errorResponseMessage: { + env: 'PARSE_SERVER_RATE_LIMIT_ERROR_RESPONSE_MESSAGE', + help: + 'The error message that should be returned in the body of the HTTP 429 response when the rate limit is hit. Default is `Too many requests.`.', + default: 'Too many requests.', + }, + includeInternalRequests: { + env: 'PARSE_SERVER_RATE_LIMIT_INCLUDE_INTERNAL_REQUESTS', + help: + 'Optional, if `true` the rate limit will also apply to requests that are made in by Cloud Code, default is `false`. Note that a public Cloud Code function that triggers internal requests may circumvent rate limiting and be vulnerable to attacks.', + action: parsers.booleanParser, + default: false, + }, + includeMasterKey: { + env: 'PARSE_SERVER_RATE_LIMIT_INCLUDE_MASTER_KEY', + help: + 'Optional, if `true` the rate limit will also apply to requests using the `masterKey`, default is `false`. Note that a public Cloud Code function that triggers internal requests using the `masterKey` may circumvent rate limiting and be vulnerable to attacks.', + action: parsers.booleanParser, + default: false, + }, + redisUrl: { + env: 'PARSE_SERVER_RATE_LIMIT_REDIS_URL', + help: + 'Optional, the URL of the Redis server to store rate limit data. This allows to rate limit requests for multiple servers by calculating the sum of all requests across all servers. This is useful if multiple servers are processing requests behind a load balancer. For example, the limit of 10 requests is reached if each of 2 servers processed 5 requests.', + }, + requestCount: { + env: 'PARSE_SERVER_RATE_LIMIT_REQUEST_COUNT', + help: + 'The number of requests that can be made per IP address within the time window set in `requestTimeWindow` before the rate limit is applied.', + action: parsers.numberParser('requestCount'), + }, + requestMethods: { + env: 'PARSE_SERVER_RATE_LIMIT_REQUEST_METHODS', + help: + 'Optional, the HTTP request methods to which the rate limit should be applied, default is all methods.', + action: parsers.arrayParser, + }, + requestPath: { + env: 'PARSE_SERVER_RATE_LIMIT_REQUEST_PATH', + help: + 'The path of the API route to be rate limited. Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expression. See: https://expressjs.com/en/guide/routing.html', + required: true, + }, + requestTimeWindow: { + env: 'PARSE_SERVER_RATE_LIMIT_REQUEST_TIME_WINDOW', + help: + 'The window of time in milliseconds within which the number of requests set in `requestCount` can be made before the rate limit is applied.', + action: parsers.numberParser('requestTimeWindow'), + }, + zone: { + env: 'PARSE_SERVER_RATE_LIMIT_ZONE', + help: + "The type of rate limit to apply. The following types are supported:

- `global`: rate limit based on the number of requests made by all users
- `ip`: rate limit based on the IP address of the request
- `user`: rate limit based on the user ID of the request
- `session`: rate limit based on the session token of the request


:default: 'ip'", + }, +}; module.exports.SecurityOptions = { checkGroups: { env: 'PARSE_SERVER_SECURITY_CHECK_GROUPS', @@ -825,6 +964,13 @@ module.exports.PasswordPolicyOptions = { 'Set the number of previous password that will not be allowed to be set as new password. If the option is not set or set to `0`, no previous passwords will be considered.

Valid values are >= `0` and <= `20`.
Default is `0`.', action: parsers.numberParser('maxPasswordHistory'), }, + resetPasswordSuccessOnInvalidEmail: { + env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_PASSWORD_SUCCESS_ON_INVALID_EMAIL', + help: + 'Set to `true` if a request to reset the password should return a success response even if the provided email address is invalid, or `false` if the request should return an error response if the email address is invalid.

Default is `true`.', + action: parsers.booleanParser, + default: true, + }, resetTokenReuseIfValid: { env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_REUSE_IF_VALID', help: @@ -873,6 +1019,13 @@ module.exports.FileUploadOptions = { action: parsers.booleanParser, default: false, }, + fileExtensions: { + env: 'PARSE_SERVER_FILE_UPLOAD_FILE_EXTENSIONS', + help: + "Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.

It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.

Defaults to `^(?!(h|H)(t|T)(m|M)(l|L)?$)` which allows any file extension except HTML files.", + action: parsers.arrayParser, + default: ['^(?!(h|H)(t|T)(m|M)(l|L)?$)'], + }, }; module.exports.DatabaseOptions = { enableSchemaHooks: { @@ -882,11 +1035,47 @@ module.exports.DatabaseOptions = { action: parsers.booleanParser, default: false, }, + schemaCacheTtl: { + env: 'PARSE_SERVER_DATABASE_SCHEMA_CACHE_TTL', + help: + 'The duration in seconds after which the schema cache expires and will be refetched from the database. Use this option if using multiple Parse Servers instances connected to the same database. A low duration will cause the schema cache to be updated too often, causing unnecessary database reads. A high duration will cause the schema to be updated too rarely, increasing the time required until schema changes propagate to all server instances. This feature can be used as an alternative or in conjunction with the option `enableSchemaHooks`. Default is infinite which means the schema cache never expires.', + action: parsers.numberParser('schemaCacheTtl'), + }, }; module.exports.AuthAdapter = { enabled: { help: 'Is `true` if the auth adapter is enabled, `false` otherwise.', action: parsers.booleanParser, - default: true, + default: false, + }, +}; +module.exports.LogLevels = { + cloudFunctionError: { + env: 'PARSE_SERVER_LOG_LEVELS_CLOUD_FUNCTION_ERROR', + help: 'Log level used by the Cloud Code Functions on error. Default is `error`.', + default: 'error', + }, + cloudFunctionSuccess: { + env: 'PARSE_SERVER_LOG_LEVELS_CLOUD_FUNCTION_SUCCESS', + help: 'Log level used by the Cloud Code Functions on success. Default is `info`.', + default: 'info', + }, + triggerAfter: { + env: 'PARSE_SERVER_LOG_LEVELS_TRIGGER_AFTER', + help: + 'Log level used by the Cloud Code Triggers `afterSave`, `afterDelete`, `afterFind`, `afterLogout`. Default is `info`.', + default: 'info', + }, + triggerBeforeError: { + env: 'PARSE_SERVER_LOG_LEVELS_TRIGGER_BEFORE_ERROR', + help: + 'Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on error. Default is `error`.', + default: 'error', + }, + triggerBeforeSuccess: { + env: 'PARSE_SERVER_LOG_LEVELS_TRIGGER_BEFORE_SUCCESS', + help: + 'Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on success. Default is `info`.', + default: 'info', }, }; diff --git a/src/Options/docs.js b/src/Options/docs.js index cbd06ecd25..219fc2e5a9 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -12,14 +12,15 @@ /** * @interface ParseServerOptions * @property {AccountLockoutOptions} accountLockout The account lockout policy for failed login attempts. - * @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true + * @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to false * @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId + * @property {Boolean} allowExpiredAuthDataToken Allow a user to log in even if the 3rd party authentication token that was used to sign in to their account has expired. If this is set to `false`, then the token will be validated every time the user signs in to their account. This refers to the token that is stored in the `_User.authData` field. Defaults to `false`. * @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers - * @property {String} allowOrigin Sets the origin to Access-Control-Allow-Origin + * @property {String|String[]} allowOrigin Sets origins for Access-Control-Allow-Origin. This can be a string for a single origin or an array of strings for multiple origins. * @property {Adapter} analyticsAdapter Adapter module for the analytics * @property {String} appId Your Parse Application ID * @property {String} appName Sets the app name - * @property {AuthAdapter[]} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication + * @property {Object} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication * @property {Adapter} cacheAdapter Adapter module for the cache * @property {Number} cacheMaxSize Sets the maximum size for the in memory cache, defaults to 10000 * @property {Number} cacheTTL Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds) @@ -27,6 +28,8 @@ * @property {String} cloud Full path to your cloud code main.js * @property {Number|Boolean} cluster Run with cluster, optionally set the number of processes default to os.cpus().length * @property {String} collectionPrefix A collection prefix for the classes + * @property {Boolean} convertEmailToLowercase Optional. If set to `true`, the `email` property of a user is automatically converted to lowercase before being stored in the database. Consequently, queries must match the case as stored in the database, which would be lowercase in this scenario. If `false`, the `email` property is stored as set, without any case modifications. Default is `false`. + * @property {Boolean} convertUsernameToLowercase Optional. If set to `true`, the `username` property of a user is automatically converted to lowercase before being stored in the database. Consequently, queries must match the case as stored in the database, which would be lowercase in this scenario. If `false`, the `username` property is stored as set, without any case modifications. Default is `false`. * @property {CustomPagesOptions} customPages custom pages for password validation and reset * @property {Adapter} databaseAdapter Adapter module for the database; any options that are not explicitly described here are passed directly to the database client. * @property {DatabaseOptions} databaseOptions Options to pass to the database client @@ -38,10 +41,13 @@ * @property {Boolean} emailVerifyTokenReuseIfValid Set to `true` if a email verification token should be reused in case another token is requested but there is a token that is still valid, i.e. has not expired. This avoids the often observed issue that a user requests multiple emails and does not know which link contains a valid token because each newly generated token would invalidate the previous token.

Default is `false`.
Requires option `verifyUserEmails: true`. * @property {Number} emailVerifyTokenValidityDuration Set the validity duration of the email verification token in seconds after which the token expires. The token is used in the link that is set in the email. After the token expires, the link becomes invalid and a new link has to be sent. If the option is not set or set to `undefined`, then the token never expires.

For example, to expire the token after 2 hours, set a value of 7200 seconds (= 60 seconds * 60 minutes * 2 hours).

Default is `undefined`.
Requires option `verifyUserEmails: true`. * @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true + * @property {Boolean} enableCollationCaseComparison Optional. If set to `true`, the collation rule of case comparison for queries and indexes is enabled. Enable this option to run Parse Server with MongoDB Atlas Serverless or AWS Amazon DocumentDB. If `false`, the collation rule of case comparison is disabled. Default is `false`. * @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors + * @property {Boolean} encodeParseObjectInCloudFunction If set to `true`, a `Parse.Object` that is in the payload when calling a Cloud Function will be converted to an instance of `Parse.Object`. If `false`, the object will not be converted and instead be a plain JavaScript object, which contains the raw data of a `Parse.Object` but is not an actual instance of `Parse.Object`. Default is `false`.

ℹ️ The expected behavior would be that the object is converted to an instance of `Parse.Object`, so you would normally set this option to `true`. The default is `false` because this is a temporary option that has been introduced to avoid a breaking change when fixing a bug where JavaScript objects are not converted to actual instances of `Parse.Object`. * @property {String} encryptionKey Key for encrypting your files * @property {Boolean} enforcePrivateUsers Set to true if new users should be created without public read and write access. * @property {Boolean} expireInactiveSessions Sets whether we should expire the inactive sessions, defaults to true. If false, all new sessions are created with no expiration date. + * @property {Boolean} extendSessionOnUse Whether Parse Server should automatically extend a valid session by the sessionLength * @property {String} fileKey Key for your files * @property {Adapter} filesAdapter Adapter module for the files sub-system * @property {FileUploadOptions} fileUpload Options for file uploads @@ -55,9 +61,12 @@ * @property {LiveQueryServerOptions} liveQueryServerOptions Live query server configuration options (will start the liveQuery server) * @property {Adapter} loggerAdapter Adapter module for the logging sub-system * @property {String} logLevel Sets the level for logs + * @property {LogLevels} logLevels (Optional) Overrides the log levels used internally by Parse Server to log events. * @property {String} logsFolder Folder for the logs (defaults to './logs'); set to null to disable file based logging + * @property {String} maintenanceKey (Optional) The maintenance key is used for modifying internal and read-only fields of Parse Server.

⚠️ This key is not intended to be used as part of a regular operation of Parse Server. This key is intended to conduct out-of-band changes such as one-time migrations or data correction tasks. Internal fields are not officially documented and may change at any time without publication in release changelogs. We strongly advice not to rely on internal fields as part of your regular operation and to investigate the implications of any planned changes *directly in the source code* of your current version of Parse Server. + * @property {String[]} maintenanceKeyIps (Optional) Restricts the use of maintenance key permissions to a list of IP addresses or ranges.

This option accepts a list of single IP addresses, for example `['10.0.0.1', '10.0.0.2']`. You can also use CIDR notation to specify an IP address range, for example `['10.0.1.0/24']`.

Special scenarios:
- Setting an empty array `[]` means that the maintenance key cannot be used even in Parse Server Cloud Code. This value cannot be set via an environment variable as there is no way to pass an empty array to Parse Server via an environment variable.
- Setting `['0.0.0.0/0', '::0']` means to allow any IPv4 and IPv6 address to use the maintenance key and effectively disables the IP filter.

Considerations:
- IPv4 and IPv6 addresses are not compared against each other. Each IP version (IPv4 and IPv6) needs to be considered separately. For example, `['0.0.0.0/0']` allows any IPv4 address and blocks every IPv6 address. Conversely, `['::0']` allows any IPv6 address and blocks every IPv4 address.
- Keep in mind that the IP version in use depends on the network stack of the environment in which Parse Server runs. A local environment may use a different IP version than a remote environment. For example, it's possible that locally the value `['0.0.0.0/0']` allows the request IP because the environment is using IPv4, but when Parse Server is deployed remotely the request IP is blocked because the remote environment is using IPv6.
- When setting the option via an environment variable the notation is a comma-separated string, for example `"0.0.0.0/0,::0"`.
- IPv6 zone indices (`%` suffix) are not supported, for example `fe80::1%eth0`, `fe80::1%1` or `::1%lo`.

Defaults to `['127.0.0.1', '::1']` which means that only `localhost`, the server instance on which Parse Server runs, is allowed to use the maintenance key. * @property {String} masterKey Your Parse Master Key - * @property {String[]} masterKeyIps Restrict masterKey to be used by only these ips, defaults to [] (allow all ips) + * @property {String[]} masterKeyIps (Optional) Restricts the use of master key permissions to a list of IP addresses or ranges.

This option accepts a list of single IP addresses, for example `['10.0.0.1', '10.0.0.2']`. You can also use CIDR notation to specify an IP address range, for example `['10.0.1.0/24']`.

Special scenarios:
- Setting an empty array `[]` means that the master key cannot be used even in Parse Server Cloud Code. This value cannot be set via an environment variable as there is no way to pass an empty array to Parse Server via an environment variable.
- Setting `['0.0.0.0/0', '::0']` means to allow any IPv4 and IPv6 address to use the master key and effectively disables the IP filter.

Considerations:
- IPv4 and IPv6 addresses are not compared against each other. Each IP version (IPv4 and IPv6) needs to be considered separately. For example, `['0.0.0.0/0']` allows any IPv4 address and blocks every IPv6 address. Conversely, `['::0']` allows any IPv6 address and blocks every IPv4 address.
- Keep in mind that the IP version in use depends on the network stack of the environment in which Parse Server runs. A local environment may use a different IP version than a remote environment. For example, it's possible that locally the value `['0.0.0.0/0']` allows the request IP because the environment is using IPv4, but when Parse Server is deployed remotely the request IP is blocked because the remote environment is using IPv6.
- When setting the option via an environment variable the notation is a comma-separated string, for example `"0.0.0.0/0,::0"`.
- IPv6 zone indices (`%` suffix) are not supported, for example `fe80::1%eth0`, `fe80::1%1` or `::1%lo`.

Defaults to `['127.0.0.1', '::1']` which means that only `localhost`, the server instance on which Parse Server runs, is allowed to use the master key. * @property {Number} maxLimit Max value for limit option on queries, defaults to unlimited * @property {Number|String} maxLogFiles Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null) * @property {String} maxUploadSize Max file size for uploads, defaults to 20mb @@ -72,9 +81,11 @@ * @property {Number} port The port to run the ParseServer, defaults to 1337. * @property {Boolean} preserveFileName Enable (or disable) the addition of a unique hash to the file names * @property {Boolean} preventLoginWithUnverifiedEmail Set to `true` to prevent a user from logging in if the email has not yet been verified and email verification is required.

Default is `false`.
Requires option `verifyUserEmails: true`. + * @property {Boolean} preventSignupWithUnverifiedEmail If set to `true` it prevents a user from signing up if the email has not yet been verified and email verification is required. In that case the server responds to the sign-up with HTTP status 400 and a Parse Error 205 `EMAIL_NOT_FOUND`. If set to `false` the server responds with HTTP status 200, and client SDKs return an unauthenticated Parse User without session token. In that case subsequent requests fail until the user's email address is verified.

Default is `false`.
Requires option `verifyUserEmails: true`. * @property {ProtectedFields} protectedFields Protected fields that should be treated with extra security when fetching details. * @property {String} publicServerURL Public URL to your parse server with http:// or https://. * @property {Any} push Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications + * @property {RateLimitOptions[]} rateLimit Options to limit repeated requests to Parse Server APIs. This can be used to protect sensitive endpoints such as `/requestPasswordReset` from brute-force attacks or Parse Server as a whole from denial-of-service (DoS) attacks.

ℹ️ Mind the following limitations:
- rate limits applied per IP address; this limits protection against distributed denial-of-service (DDoS) attacks where many requests are coming from various IP addresses
- if multiple Parse Server instances are behind a load balancer or ran in a cluster, each instance will calculate it's own request rates, independent from other instances; this limits the applicability of this feature when using a load balancer and another rate limiting solution that takes requests across all instances into account may be more suitable
- this feature provides basic protection against denial-of-service attacks, but a more sophisticated solution works earlier in the request flow and prevents a malicious requests to even reach a server instance; it's therefore recommended to implement a solution according to architecture and user case. * @property {String} readOnlyMasterKey Read-only key, which has the same capabilities as MasterKey without writes * @property {RequestKeywordDenylist[]} requestKeywordDenylist An array of keys and values that are prohibited in database read and write requests to prevent potential security vulnerabilities. It is possible to specify only a key (`{"key":"..."}`), only a value (`{"value":"..."}`) or a key-value pair (`{"key":"...","value":"..."}`). The specification can use the following types: `boolean`, `numeric` or `string`, where `string` will be interpreted as a regex notation. Request data is deep-scanned for matching definitions to detect also any nested occurrences. Defaults are patterns that are likely to be used in malicious requests. Setting this option will override the default patterns. * @property {String} restAPIKey Key for REST calls @@ -82,18 +93,32 @@ * @property {Boolean} scheduledPush Configuration for push scheduling, defaults to false. * @property {SchemaOptions} schema Defined schema * @property {SecurityOptions} security The security options to identify and report weak security settings. + * @property {Boolean} sendUserEmailVerification Set to `false` to prevent sending of verification email. Supports a function with a return value of `true` or `false` for conditional email sending.

Default is `true`.
* @property {Function} serverCloseComplete Callback when server has closed - * @property {Function} serverStartComplete Callback when server has started * @property {String} serverURL URL to your parse server with http:// or https://. * @property {Number} sessionLength Session duration, in seconds, defaults to 1 year * @property {Boolean} silent Disables console output * @property {Boolean} startLiveQueryServer Starts the liveQuery server + * @property {Any} trustProxy The trust proxy settings. It is important to understand the exact setup of the reverse proxy, since this setting will trust values provided in the Parse Server API request. See the express trust proxy settings documentation. Defaults to `false`. * @property {String[]} userSensitiveFields Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields * @property {Boolean} verbose Set the logging to verbose - * @property {Boolean} verifyUserEmails Set to `true` to require users to verify their email address to complete the sign-up process.

Default is `false`. + * @property {Boolean} verifyUserEmails Set to `true` to require users to verify their email address to complete the sign-up process. Supports a function with a return value of `true` or `false` for conditional verification.

Default is `false`. * @property {String} webhookKey Key sent with outgoing webhook calls */ +/** + * @interface RateLimitOptions + * @property {String} errorResponseMessage The error message that should be returned in the body of the HTTP 429 response when the rate limit is hit. Default is `Too many requests.`. + * @property {Boolean} includeInternalRequests Optional, if `true` the rate limit will also apply to requests that are made in by Cloud Code, default is `false`. Note that a public Cloud Code function that triggers internal requests may circumvent rate limiting and be vulnerable to attacks. + * @property {Boolean} includeMasterKey Optional, if `true` the rate limit will also apply to requests using the `masterKey`, default is `false`. Note that a public Cloud Code function that triggers internal requests using the `masterKey` may circumvent rate limiting and be vulnerable to attacks. + * @property {String} redisUrl Optional, the URL of the Redis server to store rate limit data. This allows to rate limit requests for multiple servers by calculating the sum of all requests across all servers. This is useful if multiple servers are processing requests behind a load balancer. For example, the limit of 10 requests is reached if each of 2 servers processed 5 requests. + * @property {Number} requestCount The number of requests that can be made per IP address within the time window set in `requestTimeWindow` before the rate limit is applied. + * @property {String[]} requestMethods Optional, the HTTP request methods to which the rate limit should be applied, default is all methods. + * @property {String} requestPath The path of the API route to be rate limited. Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expression. See: https://expressjs.com/en/guide/routing.html + * @property {Number} requestTimeWindow The window of time in milliseconds within which the number of requests set in `requestCount` can be made before the rate limit is applied. + * @property {String} zone The type of rate limit to apply. The following types are supported:

- `global`: rate limit based on the number of requests made by all users
- `ip`: rate limit based on the IP address of the request
- `user`: rate limit based on the user ID of the request
- `session`: rate limit based on the session token of the request


:default: 'ip' + */ + /** * @interface SecurityOptions * @property {CheckGroup[]} checkGroups The security check groups to run. This allows to add custom security checks or override existing ones. Default are the groups defined in `CheckGroups.js`. @@ -191,6 +216,7 @@ * @property {Boolean} doNotAllowUsername Set to `true` to disallow the username as part of the password.

Default is `false`. * @property {Number} maxPasswordAge Set the number of days after which a password expires. Login attempts fail if the user does not reset the password before expiration. * @property {Number} maxPasswordHistory Set the number of previous password that will not be allowed to be set as new password. If the option is not set or set to `0`, no previous passwords will be considered.

Valid values are >= `0` and <= `20`.
Default is `0`. + * @property {Boolean} resetPasswordSuccessOnInvalidEmail Set to `true` if a request to reset the password should return a success response even if the provided email address is invalid, or `false` if the request should return an error response if the email address is invalid.

Default is `true`. * @property {Boolean} resetTokenReuseIfValid Set to `true` if a password reset token should be reused in case another token is requested but there is a token that is still valid, i.e. has not expired. This avoids the often observed issue that a user requests multiple emails and does not know which link contains a valid token because each newly generated token would invalidate the previous token.

Default is `false`. * @property {Number} resetTokenValidityDuration Set the validity duration of the password reset token in seconds after which the token expires. The token is used in the link that is set in the email. After the token expires, the link becomes invalid and a new link has to be sent. If the option is not set or set to `undefined`, then the token never expires.

For example, to expire the token after 2 hours, set a value of 7200 seconds (= 60 seconds * 60 minutes * 2 hours).

Default is `undefined`. * @property {String} validationError Set the error message to be sent.

Default is `Password does not meet the Password Policy requirements.` @@ -203,14 +229,25 @@ * @property {Boolean} enableForAnonymousUser Is true if file upload should be allowed for anonymous users. * @property {Boolean} enableForAuthenticatedUser Is true if file upload should be allowed for authenticated users. * @property {Boolean} enableForPublic Is true if file upload should be allowed for anyone, regardless of user authentication. + * @property {String[]} fileExtensions Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.

It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.

Defaults to `^(?!(h|H)(t|T)(m|M)(l|L)?$)` which allows any file extension except HTML files. */ /** * @interface DatabaseOptions * @property {Boolean} enableSchemaHooks Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. + * @property {Number} schemaCacheTtl The duration in seconds after which the schema cache expires and will be refetched from the database. Use this option if using multiple Parse Servers instances connected to the same database. A low duration will cause the schema cache to be updated too often, causing unnecessary database reads. A high duration will cause the schema to be updated too rarely, increasing the time required until schema changes propagate to all server instances. This feature can be used as an alternative or in conjunction with the option `enableSchemaHooks`. Default is infinite which means the schema cache never expires. */ /** * @interface AuthAdapter * @property {Boolean} enabled Is `true` if the auth adapter is enabled, `false` otherwise. */ + +/** + * @interface LogLevels + * @property {String} cloudFunctionError Log level used by the Cloud Code Functions on error. Default is `error`. + * @property {String} cloudFunctionSuccess Log level used by the Cloud Code Functions on success. Default is `info`. + * @property {String} triggerAfter Log level used by the Cloud Code Triggers `afterSave`, `afterDelete`, `afterFind`, `afterLogout`. Default is `info`. + * @property {String} triggerBeforeError Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on error. Default is `error`. + * @property {String} triggerBeforeSuccess Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on success. Default is `info`. + */ diff --git a/src/Options/index.js b/src/Options/index.js index 2592e1e441..067ac15ff3 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -1,11 +1,11 @@ // @flow import { AnalyticsAdapter } from '../Adapters/Analytics/AnalyticsAdapter'; -import { FilesAdapter } from '../Adapters/Files/FilesAdapter'; -import { LoggerAdapter } from '../Adapters/Logger/LoggerAdapter'; -import { StorageAdapter } from '../Adapters/Storage/StorageAdapter'; import { CacheAdapter } from '../Adapters/Cache/CacheAdapter'; import { MailAdapter } from '../Adapters/Email/MailAdapter'; +import { FilesAdapter } from '../Adapters/Files/FilesAdapter'; +import { LoggerAdapter } from '../Adapters/Logger/LoggerAdapter'; import { PubSubAdapter } from '../Adapters/PubSub/PubSubAdapter'; +import { StorageAdapter } from '../Adapters/Storage/StorageAdapter'; import { WSSAdapter } from '../Adapters/WebSocketServer/WSSAdapter'; import { CheckGroup } from '../Security/CheckGroup'; @@ -35,6 +35,7 @@ type Adapter = string | any | T; type NumberOrBoolean = number | boolean; type NumberOrString = number | string; type ProtectedFields = any; +type StringOrStringArray = string | string[]; type RequestKeywordDenylist = { key: string | any, value: any, @@ -46,18 +47,23 @@ export interface ParseServerOptions { appId: string; /* Your Parse Master Key */ masterKey: string; + /* (Optional) The maintenance key is used for modifying internal and read-only fields of Parse Server.

⚠️ This key is not intended to be used as part of a regular operation of Parse Server. This key is intended to conduct out-of-band changes such as one-time migrations or data correction tasks. Internal fields are not officially documented and may change at any time without publication in release changelogs. We strongly advice not to rely on internal fields as part of your regular operation and to investigate the implications of any planned changes *directly in the source code* of your current version of Parse Server. */ + maintenanceKey: string; /* URL to your parse server with http:// or https://. :ENV: PARSE_SERVER_URL */ serverURL: string; - /* Restrict masterKey to be used by only these ips, defaults to [] (allow all ips) - :DEFAULT: [] */ + /* (Optional) Restricts the use of master key permissions to a list of IP addresses or ranges.

This option accepts a list of single IP addresses, for example `['10.0.0.1', '10.0.0.2']`. You can also use CIDR notation to specify an IP address range, for example `['10.0.1.0/24']`.

Special scenarios:
- Setting an empty array `[]` means that the master key cannot be used even in Parse Server Cloud Code. This value cannot be set via an environment variable as there is no way to pass an empty array to Parse Server via an environment variable.
- Setting `['0.0.0.0/0', '::0']` means to allow any IPv4 and IPv6 address to use the master key and effectively disables the IP filter.

Considerations:
- IPv4 and IPv6 addresses are not compared against each other. Each IP version (IPv4 and IPv6) needs to be considered separately. For example, `['0.0.0.0/0']` allows any IPv4 address and blocks every IPv6 address. Conversely, `['::0']` allows any IPv6 address and blocks every IPv4 address.
- Keep in mind that the IP version in use depends on the network stack of the environment in which Parse Server runs. A local environment may use a different IP version than a remote environment. For example, it's possible that locally the value `['0.0.0.0/0']` allows the request IP because the environment is using IPv4, but when Parse Server is deployed remotely the request IP is blocked because the remote environment is using IPv6.
- When setting the option via an environment variable the notation is a comma-separated string, for example `"0.0.0.0/0,::0"`.
- IPv6 zone indices (`%` suffix) are not supported, for example `fe80::1%eth0`, `fe80::1%1` or `::1%lo`.

Defaults to `['127.0.0.1', '::1']` which means that only `localhost`, the server instance on which Parse Server runs, is allowed to use the master key. + :DEFAULT: ["127.0.0.1","::1"] */ masterKeyIps: ?(string[]); + /* (Optional) Restricts the use of maintenance key permissions to a list of IP addresses or ranges.

This option accepts a list of single IP addresses, for example `['10.0.0.1', '10.0.0.2']`. You can also use CIDR notation to specify an IP address range, for example `['10.0.1.0/24']`.

Special scenarios:
- Setting an empty array `[]` means that the maintenance key cannot be used even in Parse Server Cloud Code. This value cannot be set via an environment variable as there is no way to pass an empty array to Parse Server via an environment variable.
- Setting `['0.0.0.0/0', '::0']` means to allow any IPv4 and IPv6 address to use the maintenance key and effectively disables the IP filter.

Considerations:
- IPv4 and IPv6 addresses are not compared against each other. Each IP version (IPv4 and IPv6) needs to be considered separately. For example, `['0.0.0.0/0']` allows any IPv4 address and blocks every IPv6 address. Conversely, `['::0']` allows any IPv6 address and blocks every IPv4 address.
- Keep in mind that the IP version in use depends on the network stack of the environment in which Parse Server runs. A local environment may use a different IP version than a remote environment. For example, it's possible that locally the value `['0.0.0.0/0']` allows the request IP because the environment is using IPv4, but when Parse Server is deployed remotely the request IP is blocked because the remote environment is using IPv6.
- When setting the option via an environment variable the notation is a comma-separated string, for example `"0.0.0.0/0,::0"`.
- IPv6 zone indices (`%` suffix) are not supported, for example `fe80::1%eth0`, `fe80::1%1` or `::1%lo`.

Defaults to `['127.0.0.1', '::1']` which means that only `localhost`, the server instance on which Parse Server runs, is allowed to use the maintenance key. + :DEFAULT: ["127.0.0.1","::1"] */ + maintenanceKeyIps: ?(string[]); /* Sets the app name */ appName: ?string; /* Add headers to Access-Control-Allow-Headers */ allowHeaders: ?(string[]); - /* Sets the origin to Access-Control-Allow-Origin */ - allowOrigin: ?string; + /* Sets origins for Access-Control-Allow-Origin. This can be a string for a single origin or an array of strings for multiple origins. */ + allowOrigin: ?StringOrStringArray; /* Adapter module for the analytics */ analyticsAdapter: ?Adapter; /* Adapter module for the files sub-system */ @@ -81,6 +87,9 @@ export interface ParseServerOptions { verbose: ?boolean; /* Sets the level for logs */ logLevel: ?string; + /* (Optional) Overrides the log levels used internally by Parse Server to log events. + :DEFAULT: {} */ + logLevels: ?LogLevels; /* Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null) */ maxLogFiles: ?NumberOrString; /* Disables console output @@ -94,6 +103,15 @@ export interface ParseServerOptions { databaseOptions: ?DatabaseOptions; /* Adapter module for the database; any options that are not explicitly described here are passed directly to the database client. */ databaseAdapter: ?Adapter; + /* Optional. If set to `true`, the collation rule of case comparison for queries and indexes is enabled. Enable this option to run Parse Server with MongoDB Atlas Serverless or AWS Amazon DocumentDB. If `false`, the collation rule of case comparison is disabled. Default is `false`. + :DEFAULT: false */ + enableCollationCaseComparison: ?boolean; + /* Optional. If set to `true`, the `email` property of a user is automatically converted to lowercase before being stored in the database. Consequently, queries must match the case as stored in the database, which would be lowercase in this scenario. If `false`, the `email` property is stored as set, without any case modifications. Default is `false`. + :DEFAULT: false */ + convertEmailToLowercase: ?boolean; + /* Optional. If set to `true`, the `username` property of a user is automatically converted to lowercase before being stored in the database. Consequently, queries must match the case as stored in the database, which would be lowercase in this scenario. If `false`, the `username` property is stored as set, without any case modifications. Default is `false`. + :DEFAULT: false */ + convertUsernameToLowercase: ?boolean; /* Full path to your cloud code main.js */ cloud: ?string; /* A collection prefix for the classes @@ -130,9 +148,9 @@ export interface ParseServerOptions { :ENV: PARSE_SERVER_ENABLE_ANON_USERS :DEFAULT: true */ enableAnonymousUsers: ?boolean; - /* Enable (or disable) client class creation, defaults to true + /* Enable (or disable) client class creation, defaults to false :ENV: PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION - :DEFAULT: true */ + :DEFAULT: false */ allowClientClassCreation: ?boolean; /* Enable (or disable) custom objectId :ENV: PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID @@ -140,15 +158,15 @@ export interface ParseServerOptions { allowCustomObjectId: ?boolean; /* Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication :ENV: PARSE_SERVER_AUTH_PROVIDERS */ - auth: ?(AuthAdapter[]); + auth: ?{ [string]: AuthAdapter }; /* Max file size for uploads, defaults to 20mb :DEFAULT: 20mb */ maxUploadSize: ?string; - /* Set to `true` to require users to verify their email address to complete the sign-up process. + /* Set to `true` to require users to verify their email address to complete the sign-up process. Supports a function with a return value of `true` or `false` for conditional verification.

Default is `false`. :DEFAULT: false */ - verifyUserEmails: ?boolean; + verifyUserEmails: ?(boolean | void); /* Set to `true` to prevent a user from logging in if the email has not yet been verified and email verification is required.

Default is `false`. @@ -156,6 +174,13 @@ export interface ParseServerOptions { Requires option `verifyUserEmails: true`. :DEFAULT: false */ preventLoginWithUnverifiedEmail: ?boolean; + /* If set to `true` it prevents a user from signing up if the email has not yet been verified and email verification is required. In that case the server responds to the sign-up with HTTP status 400 and a Parse Error 205 `EMAIL_NOT_FOUND`. If set to `false` the server responds with HTTP status 200, and client SDKs return an unauthenticated Parse User without session token. In that case subsequent requests fail until the user's email address is verified. +

+ Default is `false`. +
+ Requires option `verifyUserEmails: true`. + :DEFAULT: false */ + preventSignupWithUnverifiedEmail: ?boolean; /* Set the validity duration of the email verification token in seconds after which the token expires. The token is used in the link that is set in the email. After the token expires, the link becomes invalid and a new link has to be sent. If the option is not set or set to `undefined`, then the token never expires.

For example, to expire the token after 2 hours, set a value of 7200 seconds (= 60 seconds * 60 minutes * 2 hours). @@ -172,6 +197,12 @@ export interface ParseServerOptions { Requires option `verifyUserEmails: true`. :DEFAULT: false */ emailVerifyTokenReuseIfValid: ?boolean; + /* Set to `false` to prevent sending of verification email. Supports a function with a return value of `true` or `false` for conditional email sending. +

+ Default is `true`. +
+ :DEFAULT: true */ + sendUserEmailVerification: ?(boolean | void); /* The account lockout policy for failed login attempts. */ accountLockout: ?AccountLockoutOptions; /* The password policy for enforcing password related rules. */ @@ -180,6 +211,9 @@ export interface ParseServerOptions { cacheAdapter: ?Adapter; /* Adapter module for email sending */ emailAdapter: ?Adapter; + /* If set to `true`, a `Parse.Object` that is in the payload when calling a Cloud Function will be converted to an instance of `Parse.Object`. If `false`, the object will not be converted and instead be a plain JavaScript object, which contains the raw data of a `Parse.Object` but is not an actual instance of `Parse.Object`. Default is `false`.

ℹ️ The expected behavior would be that the object is converted to an instance of `Parse.Object`, so you would normally set this option to `true`. The default is `false` because this is a temporary option that has been introduced to avoid a breaking change when fixing a bug where JavaScript objects are not converted to actual instances of `Parse.Object`. + :DEFAULT: false */ + encodeParseObjectInCloudFunction: ?boolean; /* Public URL to your parse server with http:// or https://. :ENV: PARSE_PUBLIC_SERVER_URL */ publicServerURL: ?string; @@ -194,6 +228,9 @@ export interface ParseServerOptions { /* Session duration, in seconds, defaults to 1 year :DEFAULT: 31536000 */ sessionLength: ?number; + /* Whether Parse Server should automatically extend a valid session by the sessionLength + :DEFAULT: false */ + extendSessionOnUse: ?boolean; /* Default value for limit option on queries, defaults to `100`. :DEFAULT: 100 */ defaultLimit: ?number; @@ -216,7 +253,7 @@ export interface ParseServerOptions { If set to `false` then Parse requests within the same Node.js environment as Parse Server are executed as HTTP requests sent to Parse Server via the `serverURL`. For example, a `Parse.Query` in Cloud Code is calling Parse Server via a HTTP request. The server is essentially making a HTTP request to itself, unnecessarily using network resources such as network ports.

⚠️ In environments where multiple Parse Server instances run behind a load balancer and Parse requests within the current Node.js environment should be routed via the load balancer and distributed as HTTP requests among all instances via the `serverURL`, this should be set to `false`. - :DEFAULT: false */ + :DEFAULT: true */ directAccess: ?boolean; /* Enables the default express error handler for all errors :DEFAULT: false */ @@ -238,6 +275,9 @@ export interface ParseServerOptions { cluster: ?NumberOrBoolean; /* middleware for express server, can be string or function */ middleware: ?((() => void) | string); + /* The trust proxy settings. It is important to understand the exact setup of the reverse proxy, since this setting will trust values provided in the Parse Server API request. See the express trust proxy settings documentation. Defaults to `false`. + :DEFAULT: false */ + trustProxy: ?any; /* Starts the liveQuery server */ startLiveQueryServer: ?boolean; /* Live query server configuration options (will start the liveQuery server) */ @@ -268,8 +308,6 @@ export interface ParseServerOptions { :ENV: PARSE_SERVER_PLAYGROUND_PATH :DEFAULT: /playground */ playgroundPath: ?string; - /* Callback when server has started */ - serverStartComplete: ?(error: ?Error) => void; /* Defined schema :ENV: PARSE_SERVER_SCHEMA */ @@ -280,11 +318,51 @@ export interface ParseServerOptions { :DEFAULT: {} */ security: ?SecurityOptions; /* Set to true if new users should be created without public read and write access. - :DEFAULT: false */ + :DEFAULT: true */ enforcePrivateUsers: ?boolean; + /* Allow a user to log in even if the 3rd party authentication token that was used to sign in to their account has expired. If this is set to `false`, then the token will be validated every time the user signs in to their account. This refers to the token that is stored in the `_User.authData` field. Defaults to `false`. + :DEFAULT: false */ + allowExpiredAuthDataToken: ?boolean; /* An array of keys and values that are prohibited in database read and write requests to prevent potential security vulnerabilities. It is possible to specify only a key (`{"key":"..."}`), only a value (`{"value":"..."}`) or a key-value pair (`{"key":"...","value":"..."}`). The specification can use the following types: `boolean`, `numeric` or `string`, where `string` will be interpreted as a regex notation. Request data is deep-scanned for matching definitions to detect also any nested occurrences. Defaults are patterns that are likely to be used in malicious requests. Setting this option will override the default patterns. :DEFAULT: [{"key":"_bsontype","value":"Code"},{"key":"constructor"},{"key":"__proto__"}] */ requestKeywordDenylist: ?(RequestKeywordDenylist[]); + /* Options to limit repeated requests to Parse Server APIs. This can be used to protect sensitive endpoints such as `/requestPasswordReset` from brute-force attacks or Parse Server as a whole from denial-of-service (DoS) attacks.

ℹ️ Mind the following limitations:
- rate limits applied per IP address; this limits protection against distributed denial-of-service (DDoS) attacks where many requests are coming from various IP addresses
- if multiple Parse Server instances are behind a load balancer or ran in a cluster, each instance will calculate it's own request rates, independent from other instances; this limits the applicability of this feature when using a load balancer and another rate limiting solution that takes requests across all instances into account may be more suitable
- this feature provides basic protection against denial-of-service attacks, but a more sophisticated solution works earlier in the request flow and prevents a malicious requests to even reach a server instance; it's therefore recommended to implement a solution according to architecture and user case. + :DEFAULT: [] */ + rateLimit: ?(RateLimitOptions[]); +} + +export interface RateLimitOptions { + /* The path of the API route to be rate limited. Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expression. See: https://expressjs.com/en/guide/routing.html */ + requestPath: string; + /* The window of time in milliseconds within which the number of requests set in `requestCount` can be made before the rate limit is applied. */ + requestTimeWindow: ?number; + /* The number of requests that can be made per IP address within the time window set in `requestTimeWindow` before the rate limit is applied. */ + requestCount: ?number; + /* The error message that should be returned in the body of the HTTP 429 response when the rate limit is hit. Default is `Too many requests.`. + :DEFAULT: Too many requests. */ + errorResponseMessage: ?string; + /* Optional, the HTTP request methods to which the rate limit should be applied, default is all methods. */ + requestMethods: ?(string[]); + /* Optional, if `true` the rate limit will also apply to requests using the `masterKey`, default is `false`. Note that a public Cloud Code function that triggers internal requests using the `masterKey` may circumvent rate limiting and be vulnerable to attacks. + :DEFAULT: false */ + includeMasterKey: ?boolean; + /* Optional, if `true` the rate limit will also apply to requests that are made in by Cloud Code, default is `false`. Note that a public Cloud Code function that triggers internal requests may circumvent rate limiting and be vulnerable to attacks. + :DEFAULT: false */ + includeInternalRequests: ?boolean; + /* Optional, the URL of the Redis server to store rate limit data. This allows to rate limit requests for multiple servers by calculating the sum of all requests across all servers. This is useful if multiple servers are processing requests behind a load balancer. For example, the limit of 10 requests is reached if each of 2 servers processed 5 requests. + */ + redisUrl: ?string; + /* + The type of rate limit to apply. The following types are supported: +

+ - `global`: rate limit based on the number of requests made by all users
+ - `ip`: rate limit based on the IP address of the request
+ - `user`: rate limit based on the user ID of the request
+ - `session`: rate limit based on the session token of the request
+

+ :default: 'ip' + */ + zone: ?string; } export interface SecurityOptions { @@ -490,9 +568,17 @@ export interface PasswordPolicyOptions { Default is `false`. :DEFAULT: false */ resetTokenReuseIfValid: ?boolean; + /* Set to `true` if a request to reset the password should return a success response even if the provided email address is invalid, or `false` if the request should return an error response if the email address is invalid. +

+ Default is `true`. + :DEFAULT: true */ + resetPasswordSuccessOnInvalidEmail: ?boolean; } export interface FileUploadOptions { + /* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.

It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.

Defaults to `^(?!(h|H)(t|T)(m|M)(l|L)?$)` which allows any file extension except HTML files. + :DEFAULT: ["^(?!(h|H)(t|T)(m|M)(l|L)?$)"] */ + fileExtensions: ?(string[]); /* Is true if file upload should be allowed for anonymous users. :DEFAULT: false */ enableForAnonymousUser: ?boolean; @@ -508,12 +594,37 @@ export interface DatabaseOptions { /* Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. :DEFAULT: false */ enableSchemaHooks: ?boolean; + /* The duration in seconds after which the schema cache expires and will be refetched from the database. Use this option if using multiple Parse Servers instances connected to the same database. A low duration will cause the schema cache to be updated too often, causing unnecessary database reads. A high duration will cause the schema to be updated too rarely, increasing the time required until schema changes propagate to all server instances. This feature can be used as an alternative or in conjunction with the option `enableSchemaHooks`. Default is infinite which means the schema cache never expires. */ + schemaCacheTtl: ?number; } export interface AuthAdapter { /* Is `true` if the auth adapter is enabled, `false` otherwise. - :DEFAULT: true + :DEFAULT: false :ENV: */ enabled: ?boolean; } + +export interface LogLevels { + /* Log level used by the Cloud Code Triggers `afterSave`, `afterDelete`, `afterFind`, `afterLogout`. Default is `info`. + :DEFAULT: info + */ + triggerAfter: ?string; + /* Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on success. Default is `info`. + :DEFAULT: info + */ + triggerBeforeSuccess: ?string; + /* Log level used by the Cloud Code Triggers `beforeSave`, `beforeDelete`, `beforeFind`, `beforeLogin` on error. Default is `error`. + :DEFAULT: error + */ + triggerBeforeError: ?string; + /* Log level used by the Cloud Code Functions on success. Default is `info`. + :DEFAULT: info + */ + cloudFunctionSuccess: ?string; + /* Log level used by the Cloud Code Functions on error. Default is `error`. + :DEFAULT: error + */ + cloudFunctionError: ?string; +} diff --git a/src/ParseServer.js b/src/ParseServer.js index df20020d6d..85a8acc4f7 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -64,58 +64,91 @@ class ParseServer { const { appId = requiredParameter('You must provide an appId!'), masterKey = requiredParameter('You must provide a masterKey!'), - cloud, - security, javascriptKey, serverURL = requiredParameter('You must provide a serverURL!'), - serverStartComplete, - schema, } = options; // Initialize the node client SDK automatically Parse.initialize(appId, javascriptKey || 'unused', masterKey); Parse.serverURL = serverURL; + Config.validateOptions(options); const allControllers = controllers.getControllers(options); - - const { loggerController, databaseController, hooksController } = allControllers; + options.state = 'initialized'; this.config = Config.put(Object.assign({}, options, allControllers)); + this.config.masterKeyIpsStore = new Map(); + this.config.maintenanceKeyIpsStore = new Map(); + logging.setLogger(allControllers.loggerController); + } - logging.setLogger(loggerController); + /** + * Starts Parse Server as an express app; this promise resolves when Parse Server is ready to accept requests. + */ - // Note: Tests will start to fail if any validation happens after this is called. - databaseController - .performInitialization() - .then(() => hooksController.load()) - .then(async () => { - if (schema) { - await new DefinedSchemas(schema, this.config).execute(); - } - if (serverStartComplete) { - serverStartComplete(); + async start() { + try { + if (this.config.state === 'ok') { + return this; + } + this.config.state = 'starting'; + Config.put(this.config); + const { + databaseController, + hooksController, + cacheController, + cloud, + security, + schema, + liveQueryController, + } = this.config; + try { + await databaseController.performInitialization(); + } catch (e) { + if (e.code !== Parse.Error.DUPLICATE_VALUE) { + throw e; } - }) - .catch(error => { - if (serverStartComplete) { - serverStartComplete(error); + } + await hooksController.load(); + const startupPromises = []; + if (schema) { + startupPromises.push(new DefinedSchemas(schema, this.config).execute()); + } + if ( + cacheController.adapter?.connect && + typeof cacheController.adapter.connect === 'function' + ) { + startupPromises.push(cacheController.adapter.connect()); + } + startupPromises.push(liveQueryController.connect()); + await Promise.all(startupPromises); + if (cloud) { + addParseCloud(); + if (typeof cloud === 'function') { + await Promise.resolve(cloud(Parse)); + } else if (typeof cloud === 'string') { + let json; + if (process.env.npm_package_json) { + json = require(process.env.npm_package_json); + } + if (process.env.npm_package_type === 'module' || json?.type === 'module') { + await import(path.resolve(process.cwd(), cloud)); + } else { + require(path.resolve(process.cwd(), cloud)); + } } else { - console.error(error); - process.exit(1); + throw "argument 'cloud' must either be a string or a function"; } - }); - - if (cloud) { - addParseCloud(); - if (typeof cloud === 'function') { - cloud(Parse); - } else if (typeof cloud === 'string') { - require(path.resolve(process.cwd(), cloud)); - } else { - throw "argument 'cloud' must either be a string or a function"; + await new Promise(resolve => setTimeout(resolve, 10)); } - } - - if (security && security.enableCheck && security.enableCheckLog) { - new CheckRunner(options.security).run(); + if (security && security.enableCheck && security.enableCheckLog) { + new CheckRunner(security).run(); + } + this.config.state = 'ok'; + Config.put(this.config); + return this; + } catch (error) { + console.error(error); + this.config.state = 'error'; + throw error; } } @@ -140,6 +173,12 @@ class ParseServer { if (cacheAdapter && typeof cacheAdapter.handleShutdown === 'function') { promises.push(cacheAdapter.handleShutdown()); } + if (this.liveQueryServer?.server?.close) { + promises.push(new Promise(resolve => this.liveQueryServer.server.close(resolve))); + } + if (this.liveQueryServer) { + promises.push(this.liveQueryServer.shutdown()); + } return (promises.length > 0 ? Promise.all(promises) : Promise.resolve()).then(() => { if (this.config.serverCloseComplete) { this.config.serverCloseComplete(); @@ -152,7 +191,7 @@ class ParseServer { * Create an express app for the parse server * @param {Object} options let you specify the maxUploadSize when creating the express app */ static app(options) { - const { maxUploadSize = '20mb', appId, directAccess, pages } = options; + const { maxUploadSize = '20mb', appId, directAccess, pages, rateLimit = [] } = options; // This app serves the Parse API directly. // It's the equivalent of https://api.parse.com/1 in the hosted Parse API. var api = express(); @@ -167,8 +206,12 @@ class ParseServer { ); api.use('/health', function (req, res) { + res.status(options.state === 'ok' ? 200 : 503); + if (options.state === 'starting') { + res.set('Retry-After', 1); + } res.json({ - status: 'ok', + status: options.state, }); }); @@ -183,6 +226,11 @@ class ParseServer { api.use(bodyParser.json({ type: '*/*', limit: maxUploadSize })); api.use(middlewares.allowMethodOverride); api.use(middlewares.handleParseHeaders); + const routes = Array.isArray(rateLimit) ? rateLimit : [rateLimit]; + for (const route of routes) { + middlewares.addRateLimit(route, options); + } + api.use(middlewares.handleParseSession); const appRouter = ParseServer.promiseRouter({ appId }); api.use(appRouter.expressRouter()); @@ -199,12 +247,21 @@ class ParseServer { process.stderr.write(`Unable to listen on port ${err.port}. The port is already in use.`); process.exit(0); } else { - throw err; + if (err.message) { + process.stderr.write('An uncaught exception occurred: ' + err.message); + } + if (err.stack) { + process.stderr.write('Stack Trace:\n' + err.stack); + } else { + process.stderr.write(err); + } + process.exit(1); } }); // verify the server url after a 'mount' event is received /* istanbul ignore next */ - api.on('mount', function () { + api.on('mount', async function () { + await new Promise(resolve => setTimeout(resolve, 1000)); ParseServer.verifyServerUrl(); }); } @@ -251,10 +308,16 @@ class ParseServer { /** * starts the parse server's express app * @param {ParseServerOptions} options to use to start the server - * @param {Function} callback called when the server has started * @returns {ParseServer} the parse server instance */ - start(options: ParseServerOptions, callback: ?() => void) { + + async startApp(options: ParseServerOptions) { + try { + await this.start(); + } catch (e) { + console.error('Error on ParseServer.startApp: ', e); + throw e; + } const app = express(); if (options.middleware) { let middleware; @@ -265,7 +328,6 @@ class ParseServer { } app.use(middleware); } - app.use(options.mountPath, this.app); if (options.mountGraphQL === true || options.mountPlayground === true) { @@ -293,17 +355,23 @@ class ParseServer { parseGraphQLServer.applyPlayground(app); } } - - const server = app.listen(options.port, options.host, callback); + const server = await new Promise(resolve => { + app.listen(options.port, options.host, function () { + resolve(this); + }); + }); this.server = server; if (options.startLiveQueryServer || options.liveQueryServerOptions) { - this.liveQueryServer = ParseServer.createLiveQueryServer( + this.liveQueryServer = await ParseServer.createLiveQueryServer( server, options.liveQueryServerOptions, options ); } + if (options.trustProxy) { + app.set('trust proxy', options.trustProxy); + } /* istanbul ignore next */ if (!process.env.TESTING) { configureListeners(this); @@ -315,12 +383,11 @@ class ParseServer { /** * Creates a new ParseServer and starts it. * @param {ParseServerOptions} options used to start the server - * @param {Function} callback called when the server has started * @returns {ParseServer} the parse server instance */ - static start(options: ParseServerOptions, callback: ?() => void) { + static async startApp(options: ParseServerOptions) { const parseServer = new ParseServer(options); - return parseServer.start(options, callback); + return parseServer.startApp(options); } /** @@ -329,9 +396,9 @@ class ParseServer { * @param {Server} httpServer an optional http server to pass * @param {LiveQueryServerOptions} config options for the liveQueryServer * @param {ParseServerOptions} options options for the ParseServer - * @returns {ParseLiveQueryServer} the live query server instance + * @returns {Promise} the live query server instance */ - static createLiveQueryServer( + static async createLiveQueryServer( httpServer, config: LiveQueryServerOptions, options: ParseServerOptions @@ -341,42 +408,60 @@ class ParseServer { httpServer = require('http').createServer(app); httpServer.listen(config.port); } - return new ParseLiveQueryServer(httpServer, config, options); + const server = new ParseLiveQueryServer(httpServer, config, options); + await server.connect(); + return server; } - static verifyServerUrl(callback) { + static async verifyServerUrl() { // perform a health check on the serverURL value if (Parse.serverURL) { + const isValidHttpUrl = string => { + let url; + try { + url = new URL(string); + } catch (_) { + return false; + } + return url.protocol === 'http:' || url.protocol === 'https:'; + }; + const url = `${Parse.serverURL.replace(/\/$/, '')}/health`; + if (!isValidHttpUrl(url)) { + console.warn( + `\nWARNING, Unable to connect to '${Parse.serverURL}' as the URL is invalid.` + + ` Cloud code and push notifications may be unavailable!\n` + ); + return; + } const request = require('./request'); - request({ url: Parse.serverURL.replace(/\/$/, '') + '/health' }) - .catch(response => response) - .then(response => { - const json = response.data || null; - if (response.status !== 200 || !json || (json && json.status !== 'ok')) { - /* eslint-disable no-console */ - console.warn( - `\nWARNING, Unable to connect to '${Parse.serverURL}'.` + - ` Cloud code and push notifications may be unavailable!\n` - ); - /* eslint-enable no-console */ - if (callback) { - callback(false); - } - } else { - if (callback) { - callback(true); - } - } - }); + const response = await request({ url }).catch(response => response); + const json = response.data || null; + const retry = response.headers?.['retry-after']; + if (retry) { + await new Promise(resolve => setTimeout(resolve, retry * 1000)); + return this.verifyServerUrl(); + } + if (response.status !== 200 || json?.status !== 'ok') { + /* eslint-disable no-console */ + console.warn( + `\nWARNING, Unable to connect to '${Parse.serverURL}'.` + + ` Cloud code and push notifications may be unavailable!\n` + ); + /* eslint-enable no-console */ + return; + } + return true; } } } function addParseCloud() { const ParseCloud = require('./cloud-code/Parse.Cloud'); + const ParseServer = require('./cloud-code/Parse.Server'); Object.defineProperty(Parse, 'Server', { get() { - return Config.get(Parse.applicationId); + const conf = Config.get(Parse.applicationId); + return { ...conf, ...ParseServer }; }, set(newVal) { newVal.appId = Parse.applicationId; @@ -450,10 +535,6 @@ function injectDefaults(options: ParseServerOptions) { }); } }); - - options.masterKeyIps = Array.from( - new Set(options.masterKeyIps.concat(defaults.masterKeyIps, options.masterKeyIps)) - ); } // Those can't be tested as it requires a subprocess diff --git a/src/RestQuery.js b/src/RestQuery.js index a7a4a83f54..57fc435526 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -6,6 +6,8 @@ var Parse = require('parse/node').Parse; const triggers = require('./triggers'); const { continueWhile } = require('parse/lib/node/promiseUtils'); const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL']; +const { enforceRoleSecurity } = require('./SharedRest'); + // restOptions can include: // skip // limit @@ -18,7 +20,80 @@ const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL']; // readPreference // includeReadPreference // subqueryReadPreference -function RestQuery( +/** + * Use to perform a query on a class. It will run security checks and triggers. + * @param options + * @param options.method {RestQuery.Method} The type of query to perform + * @param options.config {ParseServerConfiguration} The server configuration + * @param options.auth {Auth} The auth object for the request + * @param options.className {string} The name of the class to query + * @param options.restWhere {object} The where object for the query + * @param options.restOptions {object} The options object for the query + * @param options.clientSDK {string} The client SDK that is performing the query + * @param options.runAfterFind {boolean} Whether to run the afterFind trigger + * @param options.runBeforeFind {boolean} Whether to run the beforeFind trigger + * @param options.context {object} The context object for the query + * @returns {Promise<_UnsafeRestQuery>} A promise that is resolved with the _UnsafeRestQuery object + */ +async function RestQuery({ + method, + config, + auth, + className, + restWhere = {}, + restOptions = {}, + clientSDK, + runAfterFind = true, + runBeforeFind = true, + context, +}) { + if (![RestQuery.Method.find, RestQuery.Method.get].includes(method)) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'bad query type'); + } + enforceRoleSecurity(method, className, auth); + const result = runBeforeFind + ? await triggers.maybeRunQueryTrigger( + triggers.Types.beforeFind, + className, + restWhere, + restOptions, + config, + auth, + context, + method === RestQuery.Method.get + ) + : Promise.resolve({ restWhere, restOptions }); + + return new _UnsafeRestQuery( + config, + auth, + className, + result.restWhere || restWhere, + result.restOptions || restOptions, + clientSDK, + runAfterFind, + context + ); +} + +RestQuery.Method = Object.freeze({ + get: 'get', + find: 'find', +}); + +/** + * _UnsafeRestQuery is meant for specific internal usage only. When you need to skip security checks or some triggers. + * Don't use it if you don't know what you are doing. + * @param config + * @param auth + * @param className + * @param restWhere + * @param restOptions + * @param clientSDK + * @param runAfterFind + * @param context + */ +function _UnsafeRestQuery( config, auth, className, @@ -137,6 +212,7 @@ function RestQuery( case 'skip': case 'limit': case 'readPreference': + case 'comment': this.findOptions[option] = restOptions[option]; break; case 'order': @@ -197,7 +273,7 @@ function RestQuery( // Returns a promise for the response - an object with optional keys // 'results' and 'count'. // TODO: consolidate the replaceX functions -RestQuery.prototype.execute = function (executeOptions) { +_UnsafeRestQuery.prototype.execute = function (executeOptions) { return Promise.resolve() .then(() => { return this.buildRestWhere(); @@ -223,12 +299,15 @@ RestQuery.prototype.execute = function (executeOptions) { .then(() => { return this.runAfterFindTrigger(); }) + .then(() => { + return this.handleAuthAdapters(); + }) .then(() => { return this.response; }); }; -RestQuery.prototype.each = function (callback) { +_UnsafeRestQuery.prototype.each = function (callback) { const { config, auth, className, restWhere, restOptions, clientSDK } = this; // if the limit is set, use it restOptions.limit = restOptions.limit || 100; @@ -240,7 +319,9 @@ RestQuery.prototype.each = function (callback) { return !finished; }, async () => { - const query = new RestQuery( + // Safe here to use _UnsafeRestQuery because the security was already + // checked during "await RestQuery()" + const query = new _UnsafeRestQuery( config, auth, className, @@ -262,7 +343,7 @@ RestQuery.prototype.each = function (callback) { ); }; -RestQuery.prototype.buildRestWhere = function () { +_UnsafeRestQuery.prototype.buildRestWhere = function () { return Promise.resolve() .then(() => { return this.getUserAndRoleACL(); @@ -291,7 +372,7 @@ RestQuery.prototype.buildRestWhere = function () { }; // Uses the Auth object to get the list of roles, adds the user id -RestQuery.prototype.getUserAndRoleACL = function () { +_UnsafeRestQuery.prototype.getUserAndRoleACL = function () { if (this.auth.isMaster) { return Promise.resolve(); } @@ -310,7 +391,7 @@ RestQuery.prototype.getUserAndRoleACL = function () { // Changes the className if redirectClassNameForKey is set. // Returns a promise. -RestQuery.prototype.redirectClassNameForKey = function () { +_UnsafeRestQuery.prototype.redirectClassNameForKey = function () { if (!this.redirectKey) { return Promise.resolve(); } @@ -325,7 +406,7 @@ RestQuery.prototype.redirectClassNameForKey = function () { }; // Validates this operation against the allowClientClassCreation config. -RestQuery.prototype.validateClientClassCreation = function () { +_UnsafeRestQuery.prototype.validateClientClassCreation = function () { if ( this.config.allowClientClassCreation === false && !this.auth.isMaster && @@ -368,7 +449,7 @@ function transformInQuery(inQueryObject, className, results) { // $inQuery clause. // The $inQuery clause turns into an $in with values that are just // pointers to the objects returned in the subquery. -RestQuery.prototype.replaceInQuery = function () { +_UnsafeRestQuery.prototype.replaceInQuery = async function () { var inQueryObject = findObjectWithKey(this.restWhere, '$inQuery'); if (!inQueryObject) { return; @@ -391,13 +472,15 @@ RestQuery.prototype.replaceInQuery = function () { additionalOptions.readPreference = this.restOptions.readPreference; } - var subquery = new RestQuery( - this.config, - this.auth, - inQueryValue.className, - inQueryValue.where, - additionalOptions - ); + const subquery = await RestQuery({ + method: RestQuery.Method.find, + config: this.config, + auth: this.auth, + className: inQueryValue.className, + restWhere: inQueryValue.where, + restOptions: additionalOptions, + context: this.context, + }); return subquery.execute().then(response => { transformInQuery(inQueryObject, subquery.className, response.results); // Recurse to repeat @@ -426,7 +509,7 @@ function transformNotInQuery(notInQueryObject, className, results) { // $notInQuery clause. // The $notInQuery clause turns into a $nin with values that are just // pointers to the objects returned in the subquery. -RestQuery.prototype.replaceNotInQuery = function () { +_UnsafeRestQuery.prototype.replaceNotInQuery = async function () { var notInQueryObject = findObjectWithKey(this.restWhere, '$notInQuery'); if (!notInQueryObject) { return; @@ -449,13 +532,16 @@ RestQuery.prototype.replaceNotInQuery = function () { additionalOptions.readPreference = this.restOptions.readPreference; } - var subquery = new RestQuery( - this.config, - this.auth, - notInQueryValue.className, - notInQueryValue.where, - additionalOptions - ); + const subquery = await RestQuery({ + method: RestQuery.Method.find, + config: this.config, + auth: this.auth, + className: notInQueryValue.className, + restWhere: notInQueryValue.where, + restOptions: additionalOptions, + context: this.context, + }); + return subquery.execute().then(response => { transformNotInQuery(notInQueryObject, subquery.className, response.results); // Recurse to repeat @@ -489,7 +575,7 @@ const transformSelect = (selectObject, key, objects) => { // The $select clause turns into an $in with values selected out of // the subquery. // Returns a possible-promise. -RestQuery.prototype.replaceSelect = function () { +_UnsafeRestQuery.prototype.replaceSelect = async function () { var selectObject = findObjectWithKey(this.restWhere, '$select'); if (!selectObject) { return; @@ -519,13 +605,16 @@ RestQuery.prototype.replaceSelect = function () { additionalOptions.readPreference = this.restOptions.readPreference; } - var subquery = new RestQuery( - this.config, - this.auth, - selectValue.query.className, - selectValue.query.where, - additionalOptions - ); + const subquery = await RestQuery({ + method: RestQuery.Method.find, + config: this.config, + auth: this.auth, + className: selectValue.query.className, + restWhere: selectValue.query.where, + restOptions: additionalOptions, + context: this.context, + }); + return subquery.execute().then(response => { transformSelect(selectObject, selectValue.key, response.results); // Keep replacing $select clauses @@ -551,7 +640,7 @@ const transformDontSelect = (dontSelectObject, key, objects) => { // The $dontSelect clause turns into an $nin with values selected out of // the subquery. // Returns a possible-promise. -RestQuery.prototype.replaceDontSelect = function () { +_UnsafeRestQuery.prototype.replaceDontSelect = async function () { var dontSelectObject = findObjectWithKey(this.restWhere, '$dontSelect'); if (!dontSelectObject) { return; @@ -579,13 +668,16 @@ RestQuery.prototype.replaceDontSelect = function () { additionalOptions.readPreference = this.restOptions.readPreference; } - var subquery = new RestQuery( - this.config, - this.auth, - dontSelectValue.query.className, - dontSelectValue.query.where, - additionalOptions - ); + const subquery = await RestQuery({ + method: RestQuery.Method.find, + config: this.config, + auth: this.auth, + className: dontSelectValue.query.className, + restWhere: dontSelectValue.query.where, + restOptions: additionalOptions, + context: this.context, + }); + return subquery.execute().then(response => { transformDontSelect(dontSelectObject, dontSelectValue.key, response.results); // Keep replacing $dontSelect clauses @@ -593,7 +685,7 @@ RestQuery.prototype.replaceDontSelect = function () { }); }; -const cleanResultAuthData = function (result) { +_UnsafeRestQuery.prototype.cleanResultAuthData = function (result) { delete result.password; if (result.authData) { Object.keys(result.authData).forEach(provider => { @@ -632,7 +724,7 @@ const replaceEqualityConstraint = constraint => { return constraint; }; -RestQuery.prototype.replaceEquality = function () { +_UnsafeRestQuery.prototype.replaceEquality = function () { if (typeof this.restWhere !== 'object') { return; } @@ -643,7 +735,7 @@ RestQuery.prototype.replaceEquality = function () { // Returns a promise for whether it was successful. // Populates this.response with an object that only has 'results'. -RestQuery.prototype.runFind = function (options = {}) { +_UnsafeRestQuery.prototype.runFind = function (options = {}) { if (this.findOptions.limit === 0) { this.response = { results: [] }; return Promise.resolve(); @@ -662,7 +754,7 @@ RestQuery.prototype.runFind = function (options = {}) { .then(results => { if (this.className === '_User' && !findOptions.explain) { for (var result of results) { - cleanResultAuthData(result); + this.cleanResultAuthData(result); } } @@ -679,7 +771,7 @@ RestQuery.prototype.runFind = function (options = {}) { // Returns a promise for whether it was successful. // Populates this.response.count with the count -RestQuery.prototype.runCount = function () { +_UnsafeRestQuery.prototype.runCount = function () { if (!this.doCount) { return; } @@ -691,7 +783,7 @@ RestQuery.prototype.runCount = function () { }); }; -RestQuery.prototype.denyProtectedFields = async function () { +_UnsafeRestQuery.prototype.denyProtectedFields = async function () { if (this.auth.isMaster) { return; } @@ -716,7 +808,7 @@ RestQuery.prototype.denyProtectedFields = async function () { }; // Augments this.response with all pointers on an object -RestQuery.prototype.handleIncludeAll = function () { +_UnsafeRestQuery.prototype.handleIncludeAll = function () { if (!this.includeAll) { return; } @@ -745,7 +837,7 @@ RestQuery.prototype.handleIncludeAll = function () { }; // Updates property `this.keys` to contain all keys but the ones unselected. -RestQuery.prototype.handleExcludeKeys = function () { +_UnsafeRestQuery.prototype.handleExcludeKeys = function () { if (!this.excludeKeys) { return; } @@ -763,7 +855,7 @@ RestQuery.prototype.handleExcludeKeys = function () { }; // Augments this.response with data at the paths provided in this.include. -RestQuery.prototype.handleInclude = function () { +_UnsafeRestQuery.prototype.handleInclude = function () { if (this.include.length == 0) { return; } @@ -773,6 +865,7 @@ RestQuery.prototype.handleInclude = function () { this.auth, this.response, this.include[0], + this.context, this.restOptions ); if (pathResponse.then) { @@ -790,7 +883,7 @@ RestQuery.prototype.handleInclude = function () { }; //Returns a promise of a processed set of results -RestQuery.prototype.runAfterFindTrigger = function () { +_UnsafeRestQuery.prototype.runAfterFindTrigger = function () { if (!this.response) { return; } @@ -842,10 +935,24 @@ RestQuery.prototype.runAfterFindTrigger = function () { }); }; +_UnsafeRestQuery.prototype.handleAuthAdapters = async function () { + if (this.className !== '_User' || this.findOptions.explain) { + return; + } + await Promise.all( + this.response.results.map(result => + this.config.authDataManager.runAfterFind( + { config: this.config, auth: this.auth }, + result.authData + ) + ) + ); +}; + // Adds included values to the response. // Path is a list of field names. // Returns a promise for an augmented response. -function includePath(config, auth, response, path, restOptions = {}) { +function includePath(config, auth, response, path, context, restOptions = {}) { var pointers = findPointers(response.results, path); if (pointers.length == 0) { return response; @@ -910,7 +1017,7 @@ function includePath(config, auth, response, path, restOptions = {}) { includeRestOptions.readPreference = restOptions.readPreference; } - const queryPromises = Object.keys(pointersHash).map(className => { + const queryPromises = Object.keys(pointersHash).map(async className => { const objectIds = Array.from(pointersHash[className]); let where; if (objectIds.length === 1) { @@ -918,7 +1025,15 @@ function includePath(config, auth, response, path, restOptions = {}) { } else { where = { objectId: { $in: objectIds } }; } - var query = new RestQuery(config, auth, className, where, includeRestOptions); + const query = await RestQuery({ + method: objectIds.length === 1 ? RestQuery.Method.get : RestQuery.Method.find, + config, + auth, + className, + restWhere: where, + restOptions: includeRestOptions, + context: context, + }); return query.execute({ op: 'get' }).then(results => { results.className = className; return Promise.resolve(results); @@ -958,11 +1073,7 @@ function includePath(config, auth, response, path, restOptions = {}) { // Returns a list of pointers in REST format. function findPointers(object, path) { if (object instanceof Array) { - var answer = []; - for (var x of object) { - answer = answer.concat(findPointers(x, path)); - } - return answer; + return object.map(x => findPointers(x, path)).flat(); } if (typeof object !== 'object' || !object) { @@ -1049,3 +1160,5 @@ function findObjectWithKey(root, key) { } module.exports = RestQuery; +// For tests +module.exports._UnsafeRestQuery = _UnsafeRestQuery; diff --git a/src/RestWrite.js b/src/RestWrite.js index 3d7252a90b..b93bb2d0c8 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -16,7 +16,6 @@ const util = require('util'); import RestQuery from './RestQuery'; import _ from 'lodash'; import logger from './logger'; -import Deprecator from './Deprecator/Deprecator'; import { requiredColumns } from './Controllers/SchemaController'; // query and data are both provided in REST API format. So data @@ -65,8 +64,6 @@ function RestWrite(config, auth, className, query, data, originalData, clientSDK } } - this.checkProhibitedKeywords(data); - // When the operation is complete, this.response may have several // fields. // response: the actual data to be returned @@ -87,7 +84,10 @@ function RestWrite(config, auth, className, query, data, originalData, clientSDK // Shared SchemaController to be reused to reduce the number of loadSchema() calls per request // Once set the schemaData should be immutable this.validSchemaController = null; - this.pendingOps = {}; + this.pendingOps = { + operations: null, + identifier: null, + }; } // A convenient method to perform all the steps of processing the @@ -111,9 +111,15 @@ RestWrite.prototype.execute = function () { .then(() => { return this.validateAuthData(); }) + .then(() => { + return this.checkRestrictedFields(); + }) .then(() => { return this.runBeforeSaveTrigger(); }) + .then(() => { + return this.ensureUniqueAuthDataId(); + }) .then(() => { return this.deleteEmailResetTokenIfNeeded(); }) @@ -149,13 +155,22 @@ RestWrite.prototype.execute = function () { return this.cleanUserAuthData(); }) .then(() => { + // Append the authDataResponse if exists + if (this.authDataResponse) { + if (this.response && this.response.response) { + this.response.response.authDataResponse = this.authDataResponse; + } + } + if (this.storage.rejectSignup && this.config.preventSignupWithUnverifiedEmail) { + throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, 'User email is not verified.'); + } return this.response; }); }; // Uses the Auth object to get the list of roles, adds the user id RestWrite.prototype.getUserAndRoleACL = function () { - if (this.auth.isMaster) { + if (this.auth.isMaster || this.auth.isMaintenance) { return Promise.resolve(); } @@ -176,6 +191,7 @@ RestWrite.prototype.validateClientClassCreation = function () { if ( this.config.allowClientClassCreation === false && !this.auth.isMaster && + !this.auth.isMaintenance && SchemaController.systemClasses.indexOf(this.className) === -1 ) { return this.config.database @@ -200,7 +216,8 @@ RestWrite.prototype.validateSchema = function () { this.className, this.data, this.query, - this.runOptions + this.runOptions, + this.auth.isMaintenance ); }; @@ -219,10 +236,13 @@ RestWrite.prototype.runBeforeSaveTrigger = function () { } const { originalObject, updatedObject } = this.buildParseObjects(); - + const identifier = updatedObject._getStateIdentifier(); const stateController = Parse.CoreManager.getObjectStateController(); - const [pending] = stateController.getPendingOps(updatedObject._getStateIdentifier()); - this.pendingOps = { ...pending }; + const [pending] = stateController.getPendingOps(identifier); + this.pendingOps = { + operations: { ...pending }, + identifier, + }; return Promise.resolve() .then(() => { @@ -282,7 +302,11 @@ RestWrite.prototype.runBeforeSaveTrigger = function () { delete this.data.objectId; } } - this.checkProhibitedKeywords(this.data); + try { + Utils.checkProhibitedKeywords(this.config, this.data); + } catch (error) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, error); + } }); }; @@ -344,9 +368,36 @@ RestWrite.prototype.setRequiredFieldsIfNeeded = function () { }; // Add default fields - this.data.updatedAt = this.updatedAt; if (!this.query) { - this.data.createdAt = this.updatedAt; + // allow customizing createdAt and updatedAt when using maintenance key + if ( + this.auth.isMaintenance && + this.data.createdAt && + this.data.createdAt.__type === 'Date' + ) { + this.data.createdAt = this.data.createdAt.iso; + + if (this.data.updatedAt && this.data.updatedAt.__type === 'Date') { + const createdAt = new Date(this.data.createdAt); + const updatedAt = new Date(this.data.updatedAt.iso); + + if (updatedAt < createdAt) { + throw new Parse.Error( + Parse.Error.VALIDATION_ERROR, + 'updatedAt cannot occur before createdAt' + ); + } + + this.data.updatedAt = this.data.updatedAt.iso; + } + // if no updatedAt is provided, set it to createdAt to match default behavior + else { + this.data.updatedAt = this.data.createdAt; + } + } else { + this.data.updatedAt = this.updatedAt; + this.data.createdAt = this.updatedAt; + } // Only assign new objectId if we are creating new object if (!this.data.objectId) { @@ -358,6 +409,8 @@ RestWrite.prototype.setRequiredFieldsIfNeeded = function () { }); } } else if (schema) { + this.data.updatedAt = this.updatedAt; + Object.keys(this.data).forEach(fieldName => { setRequiredFieldIfNeeded(fieldName, false); }); @@ -375,7 +428,11 @@ RestWrite.prototype.validateAuthData = function () { return; } - if (!this.query && !this.data.authData) { + const authData = this.data.authData; + const hasUsernameAndPassword = + typeof this.data.username === 'string' && typeof this.data.password === 'string'; + + if (!this.query && !authData) { if (typeof this.data.username !== 'string' || _.isEmpty(this.data.username)) { throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'bad or missing username'); } @@ -385,10 +442,10 @@ RestWrite.prototype.validateAuthData = function () { } if ( - (this.data.authData && !Object.keys(this.data.authData).length) || + (authData && !Object.keys(authData).length) || !Object.prototype.hasOwnProperty.call(this.data, 'authData') ) { - // Handle saving authData to {} or if authData doesn't exist + // Nothing to validate here return; } else if (Object.prototype.hasOwnProperty.call(this.data, 'authData') && !this.data.authData) { // Handle saving authData to null @@ -398,15 +455,14 @@ RestWrite.prototype.validateAuthData = function () { ); } - var authData = this.data.authData; var providers = Object.keys(authData); if (providers.length > 0) { - const canHandleAuthData = providers.reduce((canHandle, provider) => { + const canHandleAuthData = providers.some(provider => { var providerAuthData = authData[provider]; var hasToken = providerAuthData && providerAuthData.id; - return canHandle && (hasToken || providerAuthData == null); - }, true); - if (canHandleAuthData) { + return hasToken || providerAuthData === null; + }); + if (canHandleAuthData || hasUsernameAndPassword || this.auth.isMaster || this.getUserId()) { return this.handleAuthData(authData); } } @@ -416,57 +472,8 @@ RestWrite.prototype.validateAuthData = function () { ); }; -RestWrite.prototype.handleAuthDataValidation = function (authData) { - const validations = Object.keys(authData).map(provider => { - if (authData[provider] === null) { - return Promise.resolve(); - } - const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider); - const authProvider = (this.config.auth || {})[provider] || {}; - if (authProvider.enabled == null) { - Deprecator.logRuntimeDeprecation({ - usage: `auth.${provider}`, - solution: `auth.${provider}.enabled: true`, - }); - } - if (!validateAuthData || authProvider.enabled === false) { - throw new Parse.Error( - Parse.Error.UNSUPPORTED_SERVICE, - 'This authentication method is unsupported.' - ); - } - return validateAuthData(authData[provider]); - }); - return Promise.all(validations); -}; - -RestWrite.prototype.findUsersWithAuthData = function (authData) { - const providers = Object.keys(authData); - const query = providers - .reduce((memo, provider) => { - if (!authData[provider]) { - return memo; - } - const queryKey = `authData.${provider}.id`; - const query = {}; - query[queryKey] = authData[provider].id; - memo.push(query); - return memo; - }, []) - .filter(q => { - return typeof q !== 'undefined'; - }); - - let findPromise = Promise.resolve([]); - if (query.length > 0) { - findPromise = this.config.database.find(this.className, { $or: query }, {}); - } - - return findPromise; -}; - RestWrite.prototype.filteredObjectsByACL = function (objects) { - if (this.auth.isMaster) { + if (this.auth.isMaster || this.auth.isMaintenance) { return objects; } return objects.filter(object => { @@ -478,132 +485,201 @@ RestWrite.prototype.filteredObjectsByACL = function (objects) { }); }; -RestWrite.prototype.handleAuthData = function (authData) { - let results; - return this.findUsersWithAuthData(authData).then(async r => { - results = this.filteredObjectsByACL(r); - - if (results.length == 1) { - this.storage['authProvider'] = Object.keys(authData).join(','); - - const userResult = results[0]; - const mutatedAuthData = {}; - Object.keys(authData).forEach(provider => { - const providerData = authData[provider]; - const userAuthData = userResult.authData[provider]; - if (!_.isEqual(providerData, userAuthData)) { - mutatedAuthData[provider] = providerData; - } - }); - const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; - let userId; - if (this.query && this.query.objectId) { - userId = this.query.objectId; - } else if (this.auth && this.auth.user && this.auth.user.id) { - userId = this.auth.user.id; +RestWrite.prototype.getUserId = function () { + if (this.query && this.query.objectId && this.className === '_User') { + return this.query.objectId; + } else if (this.auth && this.auth.user && this.auth.user.id) { + return this.auth.user.id; + } +}; + +// Developers are allowed to change authData via before save trigger +// we need after before save to ensure that the developer +// is not currently duplicating auth data ID +RestWrite.prototype.ensureUniqueAuthDataId = async function () { + if (this.className !== '_User' || !this.data.authData) { + return; + } + + const hasAuthDataId = Object.keys(this.data.authData).some( + key => this.data.authData[key] && this.data.authData[key].id + ); + + if (!hasAuthDataId) return; + + const r = await Auth.findUsersWithAuthData(this.config, this.data.authData); + const results = this.filteredObjectsByACL(r); + if (results.length > 1) { + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } + // use data.objectId in case of login time and found user during handle validateAuthData + const userId = this.getUserId() || this.data.objectId; + if (results.length === 1 && userId !== results[0].objectId) { + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } +}; + +RestWrite.prototype.handleAuthData = async function (authData) { + const r = await Auth.findUsersWithAuthData(this.config, authData); + const results = this.filteredObjectsByACL(r); + + if (results.length > 1) { + // To avoid https://github.com/parse-community/parse-server/security/advisories/GHSA-8w3j-g983-8jh5 + // Let's run some validation before throwing + await Auth.handleAuthDataValidation(authData, this, results[0]); + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } + + // No user found with provided authData we need to validate + if (!results.length) { + const { authData: validatedAuthData, authDataResponse } = await Auth.handleAuthDataValidation( + authData, + this + ); + this.authDataResponse = authDataResponse; + // Replace current authData by the new validated one + this.data.authData = validatedAuthData; + return; + } + + // User found with provided authData + if (results.length === 1) { + const userId = this.getUserId(); + const userResult = results[0]; + // Prevent duplicate authData id + if (userId && userId !== userResult.objectId) { + await Auth.handleAuthDataValidation(authData, this, results[0]); + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } + + this.storage.authProvider = Object.keys(authData).join(','); + + const { hasMutatedAuthData, mutatedAuthData } = Auth.hasMutatedAuthData( + authData, + userResult.authData + ); + + const isCurrentUserLoggedOrMaster = + (this.auth && this.auth.user && this.auth.user.id === userResult.objectId) || + this.auth.isMaster; + + const isLogin = !userId; + + if (isLogin || isCurrentUserLoggedOrMaster) { + // no user making the call + // OR the user making the call is the right one + // Login with auth data + delete results[0].password; + + // need to set the objectId first otherwise location has trailing undefined + this.data.objectId = userResult.objectId; + + if (!this.query || !this.query.objectId) { + this.response = { + response: userResult, + location: this.location(), + }; + // Run beforeLogin hook before storing any updates + // to authData on the db; changes to userResult + // will be ignored. + await this.runBeforeLoginTrigger(deepcopy(userResult)); + + // If we are in login operation via authData + // we need to be sure that the user has provided + // required authData + Auth.checkIfUserHasProvidedConfiguredProvidersForLogin( + { config: this.config, auth: this.auth }, + authData, + userResult.authData, + this.config + ); } - if (!userId || userId === userResult.objectId) { - // no user making the call - // OR the user making the call is the right one - // Login with auth data - delete results[0].password; - - // need to set the objectId first otherwise location has trailing undefined - this.data.objectId = userResult.objectId; - - if (!this.query || !this.query.objectId) { - // this a login call, no userId passed - this.response = { - response: userResult, - location: this.location(), - }; - // Run beforeLogin hook before storing any updates - // to authData on the db; changes to userResult - // will be ignored. - await this.runBeforeLoginTrigger(deepcopy(userResult)); - } - // If we didn't change the auth data, just keep going - if (!hasMutatedAuthData) { - return; - } - // We have authData that is updated on login - // that can happen when token are refreshed, - // We should update the token and let the user in - // We should only check the mutated keys - return this.handleAuthDataValidation(mutatedAuthData).then(async () => { - // IF we have a response, we'll skip the database operation / beforeSave / afterSave etc... - // we need to set it up there. - // We are supposed to have a response only on LOGIN with authData, so we skip those - // If we're not logging in, but just updating the current user, we can safely skip that part - if (this.response) { - // Assign the new authData in the response - Object.keys(mutatedAuthData).forEach(provider => { - this.response.response.authData[provider] = mutatedAuthData[provider]; - }); + // Prevent validating if no mutated data detected on update + if (!hasMutatedAuthData && isCurrentUserLoggedOrMaster) { + return; + } - // Run the DB update directly, as 'master' - // Just update the authData part - // Then we're good for the user, early exit of sorts - return this.config.database.update( - this.className, - { objectId: this.data.objectId }, - { authData: mutatedAuthData }, - {} - ); - } + // Force to validate all provided authData on login + // on update only validate mutated ones + if (hasMutatedAuthData || !this.config.allowExpiredAuthDataToken) { + const res = await Auth.handleAuthDataValidation( + isLogin ? authData : mutatedAuthData, + this, + userResult + ); + this.data.authData = res.authData; + this.authDataResponse = res.authDataResponse; + } + + // IF we are in login we'll skip the database operation / beforeSave / afterSave etc... + // we need to set it up there. + // We are supposed to have a response only on LOGIN with authData, so we skip those + // If we're not logging in, but just updating the current user, we can safely skip that part + if (this.response) { + // Assign the new authData in the response + Object.keys(mutatedAuthData).forEach(provider => { + this.response.response.authData[provider] = mutatedAuthData[provider]; }); - } else if (userId) { - // Trying to update auth data but users - // are different - if (userResult.objectId !== userId) { - throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); - } - // No auth data was mutated, just keep going - if (!hasMutatedAuthData) { - return; + + // Run the DB update directly, as 'master' only if authData contains some keys + // authData could not contains keys after validation if the authAdapter + // uses the `doNotSave` option. Just update the authData part + // Then we're good for the user, early exit of sorts + if (Object.keys(this.data.authData).length) { + await this.config.database.update( + this.className, + { objectId: this.data.objectId }, + { authData: this.data.authData }, + {} + ); } } } - return this.handleAuthDataValidation(authData).then(() => { - if (results.length > 1) { - // More than 1 user with the passed id's - throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); - } - }); - }); + } }; -// The non-third-party parts of User transformation -RestWrite.prototype.transformUser = function () { - var promise = Promise.resolve(); - +RestWrite.prototype.checkRestrictedFields = async function () { if (this.className !== '_User') { - return promise; + return; } - if (!this.auth.isMaster && 'emailVerified' in this.data) { + if (!this.auth.isMaintenance && !this.auth.isMaster && 'emailVerified' in this.data) { const error = `Clients aren't allowed to manually update email verification.`; throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); } +}; + +// The non-third-party parts of User transformation +RestWrite.prototype.transformUser = async function () { + var promise = Promise.resolve(); + if (this.className !== '_User') { + return promise; + } // Do not cleanup session if objectId is not set if (this.query && this.objectId()) { // If we're updating a _User object, we need to clear out the cache for that user. Find all their // session tokens, and remove them from the cache. - promise = new RestQuery(this.config, Auth.master(this.config), '_Session', { - user: { - __type: 'Pointer', - className: '_User', - objectId: this.objectId(), + const query = await RestQuery({ + method: RestQuery.Method.find, + config: this.config, + auth: Auth.master(this.config), + className: '_Session', + runBeforeFind: false, + restWhere: { + user: { + __type: 'Pointer', + className: '_User', + objectId: this.objectId(), + }, }, - }) - .execute() - .then(results => { - results.results.forEach(session => - this.config.cacheController.user.del(session.sessionToken) - ); - }); + }); + promise = query.execute().then(results => { + results.results.forEach(session => + this.config.cacheController.user.del(session.sessionToken) + ); + }); } return promise @@ -617,7 +693,7 @@ RestWrite.prototype.transformUser = function () { if (this.query) { this.storage['clearSessions'] = true; // Generate a new session only if the user requested - if (!this.auth.isMaster) { + if (!this.auth.isMaster && !this.auth.isMaintenance) { this.storage['generateNewSession'] = true; } } @@ -723,8 +799,15 @@ RestWrite.prototype._validateEmail = function () { Object.keys(this.data.authData)[0] === 'anonymous') ) { // We updated the email, send a new validation - this.storage['sendVerificationEmail'] = true; - this.config.userController.setEmailVerifyToken(this.data); + const { originalObject, updatedObject } = this.buildParseObjects(); + const request = { + original: originalObject, + object: updatedObject, + master: this.auth.isMaster, + ip: this.config.ip, + installationId: this.auth.installationId, + }; + return this.config.userController.setEmailVerifyToken(this.data, request, this.storage); } }); }; @@ -790,7 +873,8 @@ RestWrite.prototype._validatePasswordHistory = function () { .find( '_User', { objectId: this.objectId() }, - { keys: ['_password_history', '_hashed_password'] } + { keys: ['_password_history', '_hashed_password'] }, + Auth.maintenance(this.config) ) .then(results => { if (results.length != 1) { @@ -835,7 +919,7 @@ RestWrite.prototype._validatePasswordHistory = function () { return Promise.resolve(); }; -RestWrite.prototype.createSessionTokenIfNeeded = function () { +RestWrite.prototype.createSessionTokenIfNeeded = async function () { if (this.className !== '_User') { return; } @@ -847,13 +931,27 @@ RestWrite.prototype.createSessionTokenIfNeeded = function () { if (this.auth.user && this.data.authData) { return; } - if ( - !this.storage['authProvider'] && // signup call, with - this.config.preventLoginWithUnverifiedEmail && // no login without verification - this.config.verifyUserEmails - ) { - // verification is on - return; // do not create the session token in that case! + // If sign-up call + if (!this.storage.authProvider) { + // Create request object for verification functions + const { originalObject, updatedObject } = this.buildParseObjects(); + const request = { + original: originalObject, + object: updatedObject, + master: this.auth.isMaster, + ip: this.config.ip, + installationId: this.auth.installationId, + }; + // Get verification conditions which can be booleans or functions; the purpose of this async/await + // structure is to avoid unnecessarily executing subsequent functions if previous ones fail in the + // conditional statement below, as a developer may decide to execute expensive operations in them + const verifyUserEmails = async () => this.config.verifyUserEmails === true || (typeof this.config.verifyUserEmails === 'function' && await Promise.resolve(this.config.verifyUserEmails(request)) === true); + const preventLoginWithUnverifiedEmail = async () => this.config.preventLoginWithUnverifiedEmail === true || (typeof this.config.preventLoginWithUnverifiedEmail === 'function' && await Promise.resolve(this.config.preventLoginWithUnverifiedEmail(request)) === true); + // If verification is required + if (await verifyUserEmails() && await preventLoginWithUnverifiedEmail()) { + this.storage.rejectSignup = true; + return; + } } return this.createSessionToken(); }; @@ -865,15 +963,15 @@ RestWrite.prototype.createSessionToken = async function () { return; } - if (this.storage['authProvider'] == null && this.data.authData) { - this.storage['authProvider'] = Object.keys(this.data.authData).join(','); + if (this.storage.authProvider == null && this.data.authData) { + this.storage.authProvider = Object.keys(this.data.authData).join(','); } const { sessionData, createSession } = RestWrite.createSession(this.config, { userId: this.objectId(), createdWith: { - action: this.storage['authProvider'] ? 'login' : 'signup', - authProvider: this.storage['authProvider'] || 'password', + action: this.storage.authProvider ? 'login' : 'signup', + authProvider: this.storage.authProvider || 'password', }, installationId: this.auth.installationId, }); @@ -980,7 +1078,7 @@ RestWrite.prototype.handleFollowup = function () { if (this.storage && this.storage['sendVerificationEmail']) { delete this.storage['sendVerificationEmail']; // Fire and forget! - this.config.userController.sendVerificationEmail(this.data); + this.config.userController.sendVerificationEmail(this.data, { auth: this.auth }); return this.handleFollowup.bind(this); } }; @@ -992,7 +1090,7 @@ RestWrite.prototype.handleSession = function () { return; } - if (!this.auth.user && !this.auth.isMaster) { + if (!this.auth.user && !this.auth.isMaster && !this.auth.isMaintenance) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token required.'); } @@ -1025,7 +1123,7 @@ RestWrite.prototype.handleSession = function () { } } - if (!this.query && !this.auth.isMaster) { + if (!this.query && !this.auth.isMaster && !this.auth.isMaintenance) { const additionalSessionData = {}; for (var key in this.data) { if (key === 'objectId' || key === 'user') { @@ -1092,7 +1190,7 @@ RestWrite.prototype.handleInstallation = function () { let installationId = this.data.installationId; // If data.installationId is not set and we're not master, we can lookup in auth - if (!installationId && !this.auth.isMaster) { + if (!installationId && !this.auth.isMaster && !this.auth.isMaintenance) { installationId = this.auth.installationId; } @@ -1356,7 +1454,12 @@ RestWrite.prototype.runDatabaseOperation = function () { if (this.query) { // Force the user to not lockout // Matched with parse.com - if (this.className === '_User' && this.data.ACL && this.auth.isMaster !== true) { + if ( + this.className === '_User' && + this.data.ACL && + this.auth.isMaster !== true && + this.auth.isMaintenance !== true + ) { this.data.ACL[this.query.objectId] = { read: true, write: true }; } // update password timestamp if user password is being changed @@ -1383,7 +1486,8 @@ RestWrite.prototype.runDatabaseOperation = function () { .find( '_User', { objectId: this.objectId() }, - { keys: ['_password_history', '_hashed_password'] } + { keys: ['_password_history', '_hashed_password'] }, + Auth.maintenance(this.config) ) .then(results => { if (results.length != 1) { @@ -1545,17 +1649,21 @@ RestWrite.prototype.runAfterSaveTrigger = function () { const { originalObject, updatedObject } = this.buildParseObjects(); updatedObject._handleSaveResponse(this.response.response, this.response.status || 200); - this.config.database.loadSchema().then(schemaController => { - // Notifiy LiveQueryServer if possible - const perms = schemaController.getClassLevelPermissions(updatedObject.className); - this.config.liveQueryController.onAfterSave( - updatedObject.className, - updatedObject, - originalObject, - perms - ); - }); - + if (hasLiveQuery) { + this.config.database.loadSchema().then(schemaController => { + // Notify LiveQueryServer if possible + const perms = schemaController.getClassLevelPermissions(updatedObject.className); + this.config.liveQueryController.onAfterSave( + updatedObject.className, + updatedObject, + originalObject, + perms + ); + }); + } + if (!hasAfterSaveHook) { + return Promise.resolve(); + } // Run afterSave trigger return triggers .maybeRunTrigger( @@ -1569,7 +1677,7 @@ RestWrite.prototype.runAfterSaveTrigger = function () { .then(result => { const jsonReturned = result && !result._toFullJSON; if (jsonReturned) { - this.pendingOps = {}; + this.pendingOps.operations = {}; this.response.response = result; } else { this.response.response = this._updateResponseWithData( @@ -1673,10 +1781,9 @@ RestWrite.prototype.cleanUserAuthData = function () { }; RestWrite.prototype._updateResponseWithData = function (response, data) { - const { updatedObject } = this.buildParseObjects(); const stateController = Parse.CoreManager.getObjectStateController(); - const [pending] = stateController.getPendingOps(updatedObject._getStateIdentifier()); - for (const key in this.pendingOps) { + const [pending] = stateController.getPendingOps(this.pendingOps.identifier); + for (const key in this.pendingOps.operations) { if (!pending[key]) { data[key] = this.originalData ? this.originalData[key] : { __op: 'Delete' }; this.storage.fieldsChangedByTrigger.push(key); @@ -1725,20 +1832,5 @@ RestWrite.prototype._updateResponseWithData = function (response, data) { return response; }; -RestWrite.prototype.checkProhibitedKeywords = function (data) { - if (this.config.requestKeywordDenylist) { - // Scan request data for denied keywords - for (const keyword of this.config.requestKeywordDenylist) { - const match = Utils.objectContainsKeyValue(data, keyword.key, keyword.value); - if (match) { - throw new Parse.Error( - Parse.Error.INVALID_KEY_NAME, - `Prohibited keyword in request data: ${JSON.stringify(keyword)}.` - ); - } - } - } -}; - export default RestWrite; module.exports = RestWrite; diff --git a/src/Routers/AggregateRouter.js b/src/Routers/AggregateRouter.js index 7c587bedec..f8bca7fd65 100644 --- a/src/Routers/AggregateRouter.js +++ b/src/Routers/AggregateRouter.js @@ -3,7 +3,6 @@ import rest from '../rest'; import * as middleware from '../middlewares'; import Parse from 'parse/node'; import UsersRouter from './UsersRouter'; -import Deprecator from '../Deprecator/Deprecator'; export class AggregateRouter extends ClassesRouter { handleFind(req) { @@ -20,6 +19,10 @@ export class AggregateRouter extends ClassesRouter { options.explain = body.explain; delete body.explain; } + if (body.comment) { + options.comment = body.comment; + delete body.comment; + } if (body.readPreference) { options.readPreference = body.readPreference; delete body.readPreference; @@ -83,22 +86,30 @@ export class AggregateRouter extends ClassesRouter { return pipeline.map(stage => { const keys = Object.keys(stage); - if (keys.length != 1) { - throw new Error(`Pipeline stages should only have one key found ${keys.join(', ')}`); + if (keys.length !== 1) { + throw new Parse.Error( + Parse.Error.INVALID_QUERY, + `Pipeline stages should only have one key but found ${keys.join(', ')}.` + ); } return AggregateRouter.transformStage(keys[0], stage); }); } static transformStage(stageName, stage) { - if (stageName === 'group') { + const skipKeys = ['distinct', 'where']; + if (skipKeys.includes(stageName)) { + return; + } + if (stageName[0] !== '$') { + throw new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage '${stageName}'.`); + } + if (stageName === '$group') { if (Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { - Deprecator.logRuntimeDeprecation({ - usage: 'The use of objectId in aggregation stage $group', - solution: 'Use _id instead.', - }); - stage[stageName]._id = stage[stageName].objectId; - delete stage[stageName].objectId; + throw new Parse.Error( + Parse.Error.INVALID_QUERY, + `Cannot use 'objectId' in aggregation stage $group.` + ); } if (!Object.prototype.hasOwnProperty.call(stage[stageName], '_id')) { throw new Parse.Error( @@ -107,15 +118,7 @@ export class AggregateRouter extends ClassesRouter { ); } } - - if (stageName[0] !== '$') { - Deprecator.logRuntimeDeprecation({ - usage: "Using aggregation stages without a leading '$'", - solution: `Try $${stageName} instead.`, - }); - } - const key = stageName[0] === '$' ? stageName : `$${stageName}`; - return { [key]: stage[stageName] }; + return { [stageName]: stage[stageName] }; } mountRoutes() { diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index 5dfba97ee0..0a68e25254 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -166,6 +166,7 @@ export class ClassesRouter extends PromiseRouter { 'subqueryReadPreference', 'hint', 'explain', + 'comment', ]; for (const key of Object.keys(body)) { @@ -215,6 +216,9 @@ export class ClassesRouter extends PromiseRouter { if (body.explain) { options.explain = body.explain; } + if (body.comment && typeof body.comment === 'string') { + options.comment = body.comment; + } return options; } diff --git a/src/Routers/FilesRouter.js b/src/Routers/FilesRouter.js index 08576de5e7..332cd75748 100644 --- a/src/Routers/FilesRouter.js +++ b/src/Routers/FilesRouter.js @@ -53,12 +53,14 @@ export class FilesRouter { limit: maxUploadSize, }), // Allow uploads without Content-Type, or with any Content-Type. Middlewares.handleParseHeaders, + Middlewares.handleParseSession, this.createHandler ); router.delete( '/files/:filename', Middlewares.handleParseHeaders, + Middlewares.handleParseSession, Middlewares.enforceMasterKeyAccess, this.deleteHandler ); @@ -138,25 +140,48 @@ export class FilesRouter { return; } + const fileExtensions = config.fileUpload?.fileExtensions; + if (!isMaster && fileExtensions) { + const isValidExtension = extension => { + return fileExtensions.some(ext => { + if (ext === '*') { + return true; + } + const regex = new RegExp(ext); + if (regex.test(extension)) { + return true; + } + }); + }; + let extension = contentType; + if (filename && filename.includes('.')) { + extension = filename.substring(filename.lastIndexOf('.') + 1); + } else if (contentType && contentType.includes('/')) { + extension = contentType.split('/')[1]; + } + extension = extension?.split(' ')?.join(''); + + if (extension && !isValidExtension(extension)) { + next( + new Parse.Error( + Parse.Error.FILE_SAVE_ERROR, + `File upload of extension ${extension} is disabled.` + ) + ); + return; + } + } + const base64 = req.body.toString('base64'); const file = new Parse.File(filename, { base64 }, contentType); const { metadata = {}, tags = {} } = req.fileData || {}; - if (req.config && req.config.requestKeywordDenylist) { + try { // Scan request data for denied keywords - for (const keyword of req.config.requestKeywordDenylist) { - const match = - Utils.objectContainsKeyValue(metadata, keyword.key, keyword.value) || - Utils.objectContainsKeyValue(tags, keyword.key, keyword.value); - if (match) { - next( - new Parse.Error( - Parse.Error.INVALID_KEY_NAME, - `Prohibited keyword in request data: ${JSON.stringify(keyword)}.` - ) - ); - return; - } - } + Utils.checkProhibitedKeywords(config, metadata); + Utils.checkProhibitedKeywords(config, tags); + } catch (error) { + next(new Parse.Error(Parse.Error.INVALID_KEY_NAME, error)); + return; } file.setTags(tags); file.setMetadata(metadata); diff --git a/src/Routers/FunctionsRouter.js b/src/Routers/FunctionsRouter.js index d239908103..eab76eeb1b 100644 --- a/src/Routers/FunctionsRouter.js +++ b/src/Routers/FunctionsRouter.js @@ -9,24 +9,30 @@ import { jobStatusHandler } from '../StatusHandler'; import _ from 'lodash'; import { logger } from '../logger'; -function parseObject(obj) { +function parseObject(obj, config) { if (Array.isArray(obj)) { return obj.map(item => { - return parseObject(item); + return parseObject(item, config); }); } else if (obj && obj.__type == 'Date') { return Object.assign(new Date(obj.iso), obj); } else if (obj && obj.__type == 'File') { return Parse.File.fromJSON(obj); + } else if (obj && obj.__type == 'Pointer' && config.encodeParseObjectInCloudFunction) { + return Parse.Object.fromJSON({ + __type: 'Pointer', + className: obj.className, + objectId: obj.objectId, + }); } else if (obj && typeof obj === 'object') { - return parseParams(obj); + return parseParams(obj, config); } else { return obj; } } -function parseParams(params) { - return _.mapValues(params, parseObject); +function parseParams(params, config) { + return _.mapValues(params, item => parseObject(item, config)); } export class FunctionsRouter extends PromiseRouter { @@ -60,7 +66,7 @@ export class FunctionsRouter extends PromiseRouter { throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Invalid job.'); } let params = Object.assign({}, req.body, req.query); - params = parseParams(params); + params = parseParams(params, req.config); const request = { params: params, log: req.config.loggerController, @@ -120,7 +126,7 @@ export class FunctionsRouter extends PromiseRouter { throw new Parse.Error(Parse.Error.SCRIPT_FAILED, `Invalid function: "${functionName}"`); } let params = Object.assign({}, req.body, req.query); - params = parseParams(params); + params = parseParams(params, req.config); const request = { params: params, master: req.auth && req.auth.isMaster, @@ -140,7 +146,7 @@ export class FunctionsRouter extends PromiseRouter { result => { try { const cleanResult = logger.truncateLogMessage(JSON.stringify(result.response.result)); - logger.info( + logger[req.config.logLevels.cloudFunctionSuccess]( `Ran cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { functionName, @@ -155,7 +161,7 @@ export class FunctionsRouter extends PromiseRouter { }, error => { try { - logger.error( + logger[req.config.logLevels.cloudFunctionError]( `Failed running cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Error: ` + JSON.stringify(error), { diff --git a/src/Routers/PagesRouter.js b/src/Routers/PagesRouter.js index 5d5a1467a7..79a487b6e4 100644 --- a/src/Routers/PagesRouter.js +++ b/src/Routers/PagesRouter.js @@ -125,7 +125,7 @@ export class PagesRouter extends PromiseRouter { const userController = config.userController; - return userController.resendVerificationEmail(username).then( + return userController.resendVerificationEmail(username, req).then( () => { return this.goToPage(req, pages.emailVerificationSendSuccess); }, diff --git a/src/Routers/PublicAPIRouter.js b/src/Routers/PublicAPIRouter.js index 5009ee7d22..ddef76a5b8 100644 --- a/src/Routers/PublicAPIRouter.js +++ b/src/Routers/PublicAPIRouter.js @@ -63,7 +63,7 @@ export class PublicAPIRouter extends PromiseRouter { const userController = config.userController; - return userController.resendVerificationEmail(username).then( + return userController.resendVerificationEmail(username, req).then( () => { return Promise.resolve({ status: 302, diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index cdce6a1348..8af8dc5434 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -7,9 +7,15 @@ import ClassesRouter from './ClassesRouter'; import rest from '../rest'; import Auth from '../Auth'; import passwordCrypto from '../password'; -import { maybeRunTrigger, Types as TriggerTypes } from '../triggers'; +import { + maybeRunTrigger, + Types as TriggerTypes, + getRequestObject, + resolveError, +} from '../triggers'; import { promiseEnsureIdempotency } from '../middlewares'; import RestWrite from '../RestWrite'; +import { logger } from '../logger'; export class UsersRouter extends ClassesRouter { className() { @@ -69,7 +75,7 @@ export class UsersRouter extends ClassesRouter { ) { payload = req.query; } - const { username, email, password } = payload; + const { username, email, password, ignoreEmailVerification } = payload; // TODO: use the right error codes / descriptions. if (!username && !email) { @@ -97,7 +103,7 @@ export class UsersRouter extends ClassesRouter { query = { $or: [{ username }, { email: username }] }; } return req.config.database - .find('_User', query) + .find('_User', query, {}, Auth.maintenance(req.config)) .then(results => { if (!results.length) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); @@ -120,7 +126,7 @@ export class UsersRouter extends ClassesRouter { const accountLockoutPolicy = new AccountLockout(user, req.config); return accountLockoutPolicy.handleLoginAttempt(isValidPassword); }) - .then(() => { + .then(async () => { if (!isValidPassword) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); } @@ -131,12 +137,25 @@ export class UsersRouter extends ClassesRouter { if (!req.auth.isMaster && user.ACL && Object.keys(user.ACL).length == 0) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); } - if ( - req.config.verifyUserEmails && - req.config.preventLoginWithUnverifiedEmail && - !user.emailVerified - ) { - throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, 'User email is not verified.'); + // Create request object for verification functions + const request = { + master: req.auth.isMaster, + ip: req.config.ip, + installationId: req.auth.installationId, + object: Parse.User.fromJSON(Object.assign({ className: '_User' }, user)), + }; + + // If request doesn't use master or maintenance key with ignoring email verification + if (!((req.auth.isMaster || req.auth.isMaintenance) && ignoreEmailVerification)) { + + // Get verification conditions which can be booleans or functions; the purpose of this async/await + // structure is to avoid unnecessarily executing subsequent functions if previous ones fail in the + // conditional statement below, as a developer may decide to execute expensive operations in them + const verifyUserEmails = async () => req.config.verifyUserEmails === true || (typeof req.config.verifyUserEmails === 'function' && await Promise.resolve(req.config.verifyUserEmails(request)) === true); + const preventLoginWithUnverifiedEmail = async () => req.config.preventLoginWithUnverifiedEmail === true || (typeof req.config.preventLoginWithUnverifiedEmail === 'function' && await Promise.resolve(req.config.preventLoginWithUnverifiedEmail(request)) === true); + if (await verifyUserEmails() && await preventLoginWithUnverifiedEmail() && !user.emailVerified) { + throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, 'User email is not verified.'); + } } this._sanitizeAuthData(user); @@ -174,7 +193,6 @@ export class UsersRouter extends ClassesRouter { // Remove hidden properties. UsersRouter.removeHiddenProperties(user); - return { response: user }; } }); @@ -182,6 +200,35 @@ export class UsersRouter extends ClassesRouter { async handleLogIn(req) { const user = await this._authenticateUserFromRequest(req); + const authData = req.body && req.body.authData; + // Check if user has provided their required auth providers + Auth.checkIfUserHasProvidedConfiguredProvidersForLogin( + req, + authData, + user.authData, + req.config + ); + + let authDataResponse; + let validatedAuthData; + if (authData) { + const res = await Auth.handleAuthDataValidation( + authData, + new RestWrite( + req.config, + req.auth, + '_User', + { objectId: user.objectId }, + req.body, + user, + req.info.clientSDK, + req.info.context + ), + user + ); + authDataResponse = res.authDataResponse; + validatedAuthData = res.authData; + } // handle password expiry policy if (req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { @@ -225,9 +272,20 @@ export class UsersRouter extends ClassesRouter { req.auth, Parse.User.fromJSON(Object.assign({ className: '_User' }, user)), null, - req.config + req.config, + req.info.context ); + // If we have some new validated authData update directly + if (validatedAuthData && Object.keys(validatedAuthData).length) { + await req.config.database.update( + '_User', + { objectId: user.objectId }, + { authData: validatedAuthData }, + {} + ); + } + const { sessionData, createSession } = RestWrite.createSession(req.config, { userId: user.objectId, createdWith: { @@ -242,14 +300,20 @@ export class UsersRouter extends ClassesRouter { await createSession(); const afterLoginUser = Parse.User.fromJSON(Object.assign({ className: '_User' }, user)); - maybeRunTrigger( + await maybeRunTrigger( TriggerTypes.afterLogin, { ...req.auth, user: afterLoginUser }, afterLoginUser, null, - req.config + req.config, + req.info.context ); + if (authDataResponse) { + user.authDataResponse = authDataResponse; + } + await req.config.authDataManager.runAfterFind(req, user.authData); + return { response: user }; } @@ -317,49 +381,36 @@ export class UsersRouter extends ClassesRouter { }); } - handleLogOut(req) { + async handleLogOut(req) { const success = { response: {} }; if (req.info && req.info.sessionToken) { - return rest - .find( + const records = await rest.find( + req.config, + Auth.master(req.config), + '_Session', + { sessionToken: req.info.sessionToken }, + undefined, + req.info.clientSDK, + req.info.context + ); + if (records.results && records.results.length) { + await rest.del( req.config, Auth.master(req.config), '_Session', - { sessionToken: req.info.sessionToken }, - undefined, - req.info.clientSDK, + records.results[0].objectId, req.info.context - ) - .then(records => { - if (records.results && records.results.length) { - return rest - .del( - req.config, - Auth.master(req.config), - '_Session', - records.results[0].objectId, - req.info.context - ) - .then(() => { - this._runAfterLogoutTrigger(req, records.results[0]); - return Promise.resolve(success); - }); - } - return Promise.resolve(success); - }); + ); + await maybeRunTrigger( + TriggerTypes.afterLogout, + req.auth, + Parse.Session.fromJSON(Object.assign({ className: '_Session' }, records.results[0])), + null, + req.config + ); + } } - return Promise.resolve(success); - } - - _runAfterLogoutTrigger(req, session) { - // After logout trigger - maybeRunTrigger( - TriggerTypes.afterLogout, - req.auth, - Parse.Session.fromJSON(Object.assign({ className: '_Session' }, session)), - null, - req.config - ); + return success; } _throwOnBadEmailConfig(req) { @@ -384,7 +435,7 @@ export class UsersRouter extends ClassesRouter { } } - handleResetRequest(req) { + async handleResetRequest(req) { this._throwOnBadEmailConfig(req); const { email } = req.body; @@ -398,27 +449,25 @@ export class UsersRouter extends ClassesRouter { ); } const userController = req.config.userController; - return userController.sendPasswordResetEmail(email).then( - () => { - return Promise.resolve({ - response: {}, - }); - }, - err => { - if (err.code === Parse.Error.OBJECT_NOT_FOUND) { - // Return success so that this endpoint can't - // be used to enumerate valid emails - return Promise.resolve({ + try { + await userController.sendPasswordResetEmail(email); + return { + response: {}, + }; + } catch (err) { + if (err.code === Parse.Error.OBJECT_NOT_FOUND) { + if (req.config.passwordPolicy?.resetPasswordSuccessOnInvalidEmail ?? true) { + return { response: {}, - }); - } else { - throw err; + }; } + err.message = `A user with that email does not exist.`; } - ); + throw err; + } } - handleVerificationEmailRequest(req) { + async handleVerificationEmailRequest(req) { this._throwOnBadEmailConfig(req); const { email } = req.body; @@ -432,25 +481,146 @@ export class UsersRouter extends ClassesRouter { ); } - return req.config.database.find('_User', { email: email }).then(results => { - if (!results.length || results.length < 1) { - throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); + const results = await req.config.database.find('_User', { email: email }, {}, Auth.maintenance(req.config)); + if (!results.length || results.length < 1) { + throw new Parse.Error(Parse.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); + } + const user = results[0]; + + // remove password field, messes with saving on postgres + delete user.password; + + if (user.emailVerified) { + throw new Parse.Error(Parse.Error.OTHER_CAUSE, `Email ${email} is already verified.`); + } + + const userController = req.config.userController; + const send = await userController.regenerateEmailVerifyToken(user, req.auth.isMaster, req.auth.installationId, req.ip); + if (send) { + userController.sendVerificationEmail(user, req); + } + return { response: {} }; + } + + async handleChallenge(req) { + const { username, email, password, authData, challengeData } = req.body; + + // if username or email provided with password try to authenticate the user by username + let user; + if (username || email) { + if (!password) { + throw new Parse.Error( + Parse.Error.OTHER_CAUSE, + 'You provided username or email, you need to also provide password.' + ); } - const user = results[0]; + user = await this._authenticateUserFromRequest(req); + } - // remove password field, messes with saving on postgres - delete user.password; + if (!challengeData) { + throw new Parse.Error(Parse.Error.OTHER_CAUSE, 'Nothing to challenge.'); + } - if (user.emailVerified) { - throw new Parse.Error(Parse.Error.OTHER_CAUSE, `Email ${email} is already verified.`); + if (typeof challengeData !== 'object') { + throw new Parse.Error(Parse.Error.OTHER_CAUSE, 'challengeData should be an object.'); + } + + let request; + let parseUser; + + // Try to find user by authData + if (authData) { + if (typeof authData !== 'object') { + throw new Parse.Error(Parse.Error.OTHER_CAUSE, 'authData should be an object.'); + } + if (user) { + throw new Parse.Error( + Parse.Error.OTHER_CAUSE, + 'You cannot provide username/email and authData, only use one identification method.' + ); } - const userController = req.config.userController; - return userController.regenerateEmailVerifyToken(user).then(() => { - userController.sendVerificationEmail(user); - return { response: {} }; - }); - }); + if (Object.keys(authData).filter(key => authData[key].id).length > 1) { + throw new Parse.Error( + Parse.Error.OTHER_CAUSE, + 'You cannot provide more than one authData provider with an id.' + ); + } + + const results = await Auth.findUsersWithAuthData(req.config, authData); + + try { + if (!results[0] || results.length > 1) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.'); + } + // Find the provider used to find the user + const provider = Object.keys(authData).find(key => authData[key].id); + + parseUser = Parse.User.fromJSON({ className: '_User', ...results[0] }); + request = getRequestObject(undefined, req.auth, parseUser, parseUser, req.config); + request.isChallenge = true; + // Validate authData used to identify the user to avoid brute-force attack on `id` + const { validator } = req.config.authDataManager.getValidatorForProvider(provider); + const validatorResponse = await validator(authData[provider], req, parseUser, request); + if (validatorResponse && validatorResponse.validator) { + await validatorResponse.validator(); + } + } catch (e) { + // Rewrite the error to avoid guess id attack + logger.error(e); + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.'); + } + } + + if (!parseUser) { + parseUser = user ? Parse.User.fromJSON({ className: '_User', ...user }) : undefined; + } + + if (!request) { + request = getRequestObject(undefined, req.auth, parseUser, parseUser, req.config); + request.isChallenge = true; + } + const acc = {}; + // Execute challenge step-by-step with consistent order for better error feedback + // and to avoid to trigger others challenges if one of them fails + for (const provider of Object.keys(challengeData).sort()) { + try { + const authAdapter = req.config.authDataManager.getValidatorForProvider(provider); + if (!authAdapter) { + continue; + } + const { + adapter: { challenge }, + } = authAdapter; + if (typeof challenge === 'function') { + const providerChallengeResponse = await challenge( + challengeData[provider], + authData && authData[provider], + req.config.auth[provider], + request + ); + acc[provider] = providerChallengeResponse || true; + } + } catch (err) { + const e = resolveError(err, { + code: Parse.Error.SCRIPT_FAILED, + message: 'Challenge failed. Unknown error.', + }); + const userString = req.auth && req.auth.user ? req.auth.user.id : undefined; + logger.error( + `Failed running auth step challenge for ${provider} for user ${userString} with Error: ` + + JSON.stringify(e), + { + authenticationStep: 'challenge', + error: e, + user: userString, + provider, + } + ); + throw e; + } + } + return { response: { challengeData: acc } }; } mountRoutes() { @@ -493,6 +663,12 @@ export class UsersRouter extends ClassesRouter { this.route('GET', '/verifyPassword', req => { return this.handleVerifyPassword(req); }); + this.route('POST', '/verifyPassword', req => { + return this.handleVerifyPassword(req); + }); + this.route('POST', '/challenge', req => { + return this.handleChallenge(req); + }); } } diff --git a/src/SchemaMigrations/DefinedSchemas.js b/src/SchemaMigrations/DefinedSchemas.js index 5ab737122f..c3a9baab2e 100644 --- a/src/SchemaMigrations/DefinedSchemas.js +++ b/src/SchemaMigrations/DefinedSchemas.js @@ -7,6 +7,8 @@ import { internalCreateSchema, internalUpdateSchema } from '../Routers/SchemasRo import { defaultColumns, systemClasses } from '../Controllers/SchemaController'; import { ParseServerOptions } from '../Options'; import * as Migrations from './Migrations'; +import Auth from '../Auth'; +import rest from '../rest'; export class DefinedSchemas { config: ParseServerOptions; @@ -96,9 +98,10 @@ export class DefinedSchemas { }, 20000); } - // Hack to force session schema to be created await this.createDeleteSession(); - this.allCloudSchemas = await Parse.Schema.all(); + // @flow-disable-next-line + const schemaController = await this.config.database.loadSchema(); + this.allCloudSchemas = await schemaController.getAllClasses(); clearTimeout(timeout); await Promise.all(this.localSchemas.map(async localSchema => this.saveOrUpdate(localSchema))); @@ -171,9 +174,8 @@ export class DefinedSchemas { // Create a fake session since Parse do not create the _Session until // a session is created async createDeleteSession() { - const session = new Parse.Session(); - await session.save(null, { useMasterKey: true }); - await session.destroy({ useMasterKey: true }); + const { response } = await rest.create(this.config, Auth.master(this.config), '_Session', {}); + await rest.del(this.config, Auth.master(this.config), '_Session', response.objectId); } async saveOrUpdate(localSchema: Migrations.JSONSchema) { diff --git a/src/Security/Check.js b/src/Security/Check.js index dc57d63088..c31480e73d 100644 --- a/src/Security/Check.js +++ b/src/Security/Check.js @@ -7,7 +7,7 @@ import { isFunction, isString } from 'lodash'; /** * A security check. - * @class Check + * @class */ class Check { /** diff --git a/src/Security/CheckGroup.js b/src/Security/CheckGroup.js index a9fde2905f..d8e3f8e08e 100644 --- a/src/Security/CheckGroup.js +++ b/src/Security/CheckGroup.js @@ -1,10 +1,7 @@ -/** - * @module SecurityCheck - */ - /** * A group of security checks. - * @interface CheckGroup + * @interface + * @memberof module:SecurityCheck */ class CheckGroup { constructor() { diff --git a/src/Security/CheckGroups/CheckGroupDatabase.js b/src/Security/CheckGroups/CheckGroupDatabase.js index d0da79a4ba..bc57fef8a3 100644 --- a/src/Security/CheckGroups/CheckGroupDatabase.js +++ b/src/Security/CheckGroups/CheckGroupDatabase.js @@ -1,16 +1,13 @@ -/** - * @module SecurityCheck - */ - import { Check } from '../Check'; import CheckGroup from '../CheckGroup'; import Config from '../../Config'; import Parse from 'parse/node'; /** -* The security checks group for Parse Server configuration. -* Checks common Parse Server parameters such as access keys. -*/ + * The security checks group for Parse Server configuration. + * Checks common Parse Server parameters such as access keys + * @memberof module:SecurityCheck + */ class CheckGroupDatabase extends CheckGroup { setName() { return 'Database'; @@ -23,7 +20,8 @@ class CheckGroupDatabase extends CheckGroup { new Check({ title: 'Secure database password', warning: 'The database password is insecure and vulnerable to brute force attacks.', - solution: 'Choose a longer and/or more complex password with a combination of upper- and lowercase characters, numbers and special characters.', + solution: + 'Choose a longer and/or more complex password with a combination of upper- and lowercase characters, numbers and special characters.', check: () => { const password = databaseUrl.match(/\/\/\S+:(\S+)@/)[1]; const hasUpperCase = /[A-Z]/.test(password); diff --git a/src/Security/CheckGroups/CheckGroupServerConfig.js b/src/Security/CheckGroups/CheckGroupServerConfig.js index a9c6e671cc..b2b2376cb1 100644 --- a/src/Security/CheckGroups/CheckGroupServerConfig.js +++ b/src/Security/CheckGroups/CheckGroupServerConfig.js @@ -1,7 +1,3 @@ -/** - * @module SecurityCheck - */ - import { Check } from '../Check'; import CheckGroup from '../CheckGroup'; import Config from '../../Config'; @@ -10,6 +6,7 @@ import Parse from 'parse/node'; /** * The security checks group for Parse Server configuration. * Checks common Parse Server parameters such as access keys. + * @memberof module:SecurityCheck */ class CheckGroupServerConfig extends CheckGroup { setName() { diff --git a/src/Security/CheckGroups/CheckGroups.js b/src/Security/CheckGroups/CheckGroups.js index d1c4f03d8c..36f90e019c 100644 --- a/src/Security/CheckGroups/CheckGroups.js +++ b/src/Security/CheckGroups/CheckGroups.js @@ -1,5 +1,5 @@ /** - * @module SecurityCheck + * @memberof module:SecurityCheck */ /** diff --git a/src/Security/CheckRunner.js b/src/Security/CheckRunner.js index a662ffbad4..4be1c3acbf 100644 --- a/src/Security/CheckRunner.js +++ b/src/Security/CheckRunner.js @@ -1,7 +1,3 @@ -/** - * @module SecurityCheck - */ - import Utils from '../Utils'; import { CheckState } from './Check'; import * as CheckGroups from './CheckGroups/CheckGroups'; @@ -10,6 +6,7 @@ import { isArray, isBoolean } from 'lodash'; /** * The security check runner. + * @memberof module:SecurityCheck */ class CheckRunner { /** diff --git a/src/SharedRest.js b/src/SharedRest.js new file mode 100644 index 0000000000..0b4a07c320 --- /dev/null +++ b/src/SharedRest.js @@ -0,0 +1,37 @@ +const classesWithMasterOnlyAccess = [ + '_JobStatus', + '_PushStatus', + '_Hooks', + '_GlobalConfig', + '_JobSchedule', + '_Idempotency', +]; +// Disallowing access to the _Role collection except by master key +function enforceRoleSecurity(method, className, auth) { + if (className === '_Installation' && !auth.isMaster && !auth.isMaintenance) { + if (method === 'delete' || method === 'find') { + const error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } + } + + //all volatileClasses are masterKey only + if ( + classesWithMasterOnlyAccess.indexOf(className) >= 0 && + !auth.isMaster && + !auth.isMaintenance + ) { + const error = `Clients aren't allowed to perform the ${method} operation on the ${className} collection.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } + + // readOnly masterKey is not allowed + if (auth.isReadOnly && (method === 'delete' || method === 'create' || method === 'update')) { + const error = `read-only masterKey isn't allowed to perform the ${method} operation.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } +} + +module.exports = { + enforceRoleSecurity, +}; diff --git a/src/TestUtils.js b/src/TestUtils.js index 7772bcd65b..6d4cfb0f14 100644 --- a/src/TestUtils.js +++ b/src/TestUtils.js @@ -1,4 +1,5 @@ import AppCache from './cache'; +import SchemaCache from './Adapters/Cache/SchemaCache'; /** * Destroys all data in the database @@ -11,11 +12,17 @@ export function destroyAllDataPermanently(fast) { return Promise.all( Object.keys(AppCache.cache).map(appId => { const app = AppCache.get(appId); + const deletePromises = []; + if (app.cacheAdapter && app.cacheAdapter.clear) { + deletePromises.push(app.cacheAdapter.clear()); + } if (app.databaseController) { - return app.databaseController.deleteEverything(fast); - } else { - return Promise.resolve(); + deletePromises.push(app.databaseController.deleteEverything(fast)); + } else if (app.databaseAdapter) { + SchemaCache.clear(); + deletePromises.push(app.databaseAdapter.deleteAllClasses(fast)); } + return Promise.all(deletePromises); }) ); } diff --git a/src/Utils.js b/src/Utils.js index d5a255a5ca..efeae58f3f 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -358,6 +358,18 @@ class Utils { } return false; } + + static checkProhibitedKeywords(config, data) { + if (config?.requestKeywordDenylist) { + // Scan request data for denied keywords + for (const keyword of config.requestKeywordDenylist) { + const match = Utils.objectContainsKeyValue(data, keyword.key, keyword.value); + if (match) { + throw `Prohibited keyword in request data: ${JSON.stringify(keyword)}.`; + } + } + } + } } module.exports = Utils; diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index 4ee9dc4c03..b0c574bfea 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -68,16 +68,26 @@ runner({ cluster.fork(); }); } else { - ParseServer.start(options, () => { - printSuccessMessage(); - }); + ParseServer.startApp(options) + .then(() => { + printSuccessMessage(); + }) + .catch(e => { + console.error(e); + process.exit(1); + }); } } else { - ParseServer.start(options, () => { - logOptions(); - console.log(''); - printSuccessMessage(); - }); + ParseServer.startApp(options) + .then(() => { + logOptions(); + console.log(''); + printSuccessMessage(); + }) + .catch(e => { + console.error(e); + process.exit(1); + }); } function printSuccessMessage() { diff --git a/src/cli/utils/commander.js b/src/cli/utils/commander.js index 8b8826fe69..75075bb3ac 100644 --- a/src/cli/utils/commander.js +++ b/src/cli/utils/commander.js @@ -136,5 +136,5 @@ Command.prototype.getOptions = function () { }, {}); }; -export default new Command(); +export default new Command().storeOptionsAsProperties(); /* eslint-enable no-console */ diff --git a/src/cli/utils/runner.js b/src/cli/utils/runner.js index d74a7a5928..4869111d64 100644 --- a/src/cli/utils/runner.js +++ b/src/cli/utils/runner.js @@ -1,13 +1,20 @@ import program from './commander'; function logStartupOptions(options) { + if (!options.verbose) { + return; + } + // Keys that may include sensitive information that will be redacted in logs + const keysToRedact = [ + 'databaseURI', + 'masterKey', + 'maintenanceKey', + 'push', + ]; for (const key in options) { let value = options[key]; - if (key == 'masterKey') { - value = '***REDACTED***'; - } - if (key == 'push' && options.verbose != true) { - value = '***REDACTED***'; + if (keysToRedact.includes(key)) { + value = ''; } if (typeof value === 'object') { try { diff --git a/src/cloud-code/HTTPResponse.js b/src/cloud-code/HTTPResponse.js deleted file mode 100644 index 1c1de93ae2..0000000000 --- a/src/cloud-code/HTTPResponse.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @typedef Parse.Cloud.HTTPResponse - * @property {Buffer} buffer The raw byte representation of the response body. Use this to receive binary data. See Buffer for more details. - * @property {Object} cookies The cookies sent by the server. The keys in this object are the names of the cookies. The values are Parse.Cloud.Cookie objects. - * @property {Object} data The parsed response body as a JavaScript object. This is only available when the response Content-Type is application/x-www-form-urlencoded or application/json. - * @property {Object} headers The headers sent by the server. The keys in this object are the names of the headers. We do not support multiple response headers with the same name. In the common case of Set-Cookie headers, please use the cookies field instead. - * @property {Number} status The status code. - * @property {String} text The raw text representation of the response body. - */ -export default class HTTPResponse { - constructor(response, body) { - let _text, _data; - this.status = response.statusCode; - this.headers = response.headers || {}; - this.cookies = this.headers['set-cookie']; - - if (typeof body == 'string') { - _text = body; - } else if (Buffer.isBuffer(body)) { - this.buffer = body; - } else if (typeof body == 'object') { - _data = body; - } - - const getText = () => { - if (!_text && this.buffer) { - _text = this.buffer.toString('utf-8'); - } else if (!_text && _data) { - _text = JSON.stringify(_data); - } - return _text; - }; - - const getData = () => { - if (!_data) { - try { - _data = JSON.parse(getText()); - } catch (e) { - /* */ - } - } - return _data; - }; - - Object.defineProperty(this, 'body', { - get: () => { - return body; - }, - }); - - Object.defineProperty(this, 'text', { - enumerable: true, - get: getText, - }); - - Object.defineProperty(this, 'data', { - enumerable: true, - get: getData, - }); - } -} diff --git a/src/cloud-code/Parse.Cloud.js b/src/cloud-code/Parse.Cloud.js index 1ee02fdb60..e37cc9b225 100644 --- a/src/cloud-code/Parse.Cloud.js +++ b/src/cloud-code/Parse.Cloud.js @@ -1,6 +1,6 @@ import { Parse } from 'parse/node'; import * as triggers from '../triggers'; -import Deprecator from '../Deprecator/Deprecator'; +import { addRateLimit } from '../middlewares'; const Config = require('../Config'); function isParseObjectConstructor(object) { @@ -28,6 +28,7 @@ function validateValidator(validator) { skipWithMasterKey: [Boolean], requireUserKeys: [Array, Object], fields: [Array, Object], + rateLimit: [Object], }; const getType = fn => { if (Array.isArray(fn)) { @@ -72,6 +73,18 @@ function validateValidator(validator) { } } } +const getRoute = parseClass => { + const route = + { + _User: 'users', + _Session: 'sessions', + '@File': 'files', + }[parseClass] || 'classes'; + if (parseClass === '@File') { + return `/${route}/:id?(.*)`; + } + return `/${route}/${parseClass}/:id?(.*)`; +}; /** @namespace * @name Parse * @description The Parse SDK. @@ -111,6 +124,13 @@ var ParseCloud = {}; ParseCloud.define = function (functionName, handler, validationHandler) { validateValidator(validationHandler); triggers.addFunction(functionName, handler, validationHandler, Parse.applicationId); + if (validationHandler && validationHandler.rateLimit) { + addRateLimit( + { requestPath: `/functions/${functionName}`, ...validationHandler.rateLimit }, + Parse.applicationId, + true + ); + } }; /** @@ -164,6 +184,17 @@ ParseCloud.beforeSave = function (parseClass, handler, validationHandler) { Parse.applicationId, validationHandler ); + if (validationHandler && validationHandler.rateLimit) { + addRateLimit( + { + requestPath: getRoute(className), + requestMethods: ['POST', 'PUT'], + ...validationHandler.rateLimit, + }, + Parse.applicationId, + true + ); + } }; /** @@ -200,6 +231,17 @@ ParseCloud.beforeDelete = function (parseClass, handler, validationHandler) { Parse.applicationId, validationHandler ); + if (validationHandler && validationHandler.rateLimit) { + addRateLimit( + { + requestPath: getRoute(className), + requestMethods: 'DELETE', + ...validationHandler.rateLimit, + }, + Parse.applicationId, + true + ); + } }; /** @@ -225,15 +267,23 @@ ParseCloud.beforeDelete = function (parseClass, handler, validationHandler) { * @name Parse.Cloud.beforeLogin * @param {Function} func The function to run before a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; */ -ParseCloud.beforeLogin = function (handler) { +ParseCloud.beforeLogin = function (handler, validationHandler) { let className = '_User'; if (typeof handler === 'string' || isParseObjectConstructor(handler)) { // validation will occur downstream, this is to maintain internal // code consistency with the other hook types. className = triggers.getClassName(handler); handler = arguments[1]; + validationHandler = arguments.length >= 2 ? arguments[2] : null; } triggers.addTrigger(triggers.Types.beforeLogin, className, handler, Parse.applicationId); + if (validationHandler && validationHandler.rateLimit) { + addRateLimit( + { requestPath: `/login`, requestMethods: 'POST', ...validationHandler.rateLimit }, + Parse.applicationId, + true + ); + } }; /** @@ -402,6 +452,17 @@ ParseCloud.beforeFind = function (parseClass, handler, validationHandler) { Parse.applicationId, validationHandler ); + if (validationHandler && validationHandler.rateLimit) { + addRateLimit( + { + requestPath: getRoute(className), + requestMethods: 'GET', + ...validationHandler.rateLimit, + }, + Parse.applicationId, + true + ); + } }; /** @@ -440,130 +501,6 @@ ParseCloud.afterFind = function (parseClass, handler, validationHandler) { ); }; -/** - * Registers a before save file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeSaveFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeSaveFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeSaveFile - * @deprecated - * @name Parse.Cloud.beforeSaveFile - * @param {Function} func The function to run before saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ -ParseCloud.beforeSaveFile = function (handler, validationHandler) { - Deprecator.logRuntimeDeprecation({ - usage: 'Parse.Cloud.beforeSaveFile', - solution: 'Use Parse.Cloud.beforeSave(Parse.File, (request) => {})', - }); - ParseCloud.beforeSave(Parse.File, handler, validationHandler); -}; - -/** - * Registers an after save file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterSaveFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterSaveFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterSaveFile - * @deprecated - * @name Parse.Cloud.afterSaveFile - * @param {Function} func The function to run after saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ -ParseCloud.afterSaveFile = function (handler, validationHandler) { - Deprecator.logRuntimeDeprecation({ - usage: 'Parse.Cloud.afterSaveFile', - solution: 'Use Parse.Cloud.afterSave(Parse.File, (request) => {})', - }); - ParseCloud.afterSave(Parse.File, handler, validationHandler); -}; - -/** - * Registers a before delete file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeDeleteFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeDeleteFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeDeleteFile - * @deprecated - * @name Parse.Cloud.beforeDeleteFile - * @param {Function} func The function to run before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ -ParseCloud.beforeDeleteFile = function (handler, validationHandler) { - Deprecator.logRuntimeDeprecation({ - usage: 'Parse.Cloud.beforeDeleteFile', - solution: 'Use Parse.Cloud.beforeDelete(Parse.File, (request) => {})', - }); - ParseCloud.beforeDelete(Parse.File, handler, validationHandler); -}; - -/** - * Registers an after delete file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterDeleteFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterDeleteFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterDeleteFile - * @deprecated - * @name Parse.Cloud.afterDeleteFile - * @param {Function} func The function to after before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ -ParseCloud.afterDeleteFile = function (handler, validationHandler) { - Deprecator.logRuntimeDeprecation({ - usage: 'Parse.Cloud.afterDeleteFile', - solution: 'Use Parse.Cloud.afterDelete(Parse.File, (request) => {})', - }); - ParseCloud.afterDelete(Parse.File, handler, validationHandler); -}; - /** * Registers a before live query server connect function. * @@ -704,6 +641,8 @@ ParseCloud.afterLiveQueryEvent = function (parseClass, handler, validationHandle ParseCloud._removeAllHooks = () => { triggers._unregisterAll(); + const config = Config.get(Parse.applicationId); + config?.unregisterRateLimiters(); }; ParseCloud.useMasterKey = () => { @@ -713,24 +652,16 @@ ParseCloud.useMasterKey = () => { ); }; -const request = require('./httpRequest'); -ParseCloud.httpRequest = opts => { - Deprecator.logRuntimeDeprecation({ - usage: 'Parse.Cloud.httpRequest', - solution: 'Use a http request library instead.', - }); - return request(opts); -}; - module.exports = ParseCloud; /** * @interface Parse.Cloud.TriggerRequest * @property {String} installationId If set, the installationId triggering the request. * @property {Boolean} master If true, means the master key was used. + * @property {Boolean} isChallenge If true, means the current request is originally triggered by an auth challenge. * @property {Parse.User} user If set, the user that made the request. * @property {Parse.Object} object The object triggering the hook. - * @property {String} ip The IP address of the client making the request. + * @property {String} ip The IP address of the client making the request. To ensure retrieving the correct IP address, set the Parse Server option `trustProxy: true` if Parse Server runs behind a proxy server, for example behind a load balancer. * @property {Object} headers The original HTTP headers for the request. * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) * @property {Object} log The current logger inside Parse Server. @@ -747,7 +678,7 @@ module.exports = ParseCloud; * @property {Integer} contentLength The value from Content-Length header * @property {String} ip The IP address of the client making the request. * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSaveFile`, `afterSaveFile`) + * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`) * @property {Object} log The current logger inside Parse Server. */ diff --git a/src/cloud-code/Parse.Server.js b/src/cloud-code/Parse.Server.js new file mode 100644 index 0000000000..71295618f2 --- /dev/null +++ b/src/cloud-code/Parse.Server.js @@ -0,0 +1,19 @@ +const ParseServer = {}; +/** + * ... + * + * @memberof Parse.Server + * @property {String} global Rate limit based on the number of requests made by all users. + * @property {String} session Rate limit based on the sessionToken. + * @property {String} user Rate limit based on the user ID. + * @property {String} ip Rate limit based on the request ip. + * ... + */ +ParseServer.RateLimitZone = Object.freeze({ + global: 'global', + session: 'session', + user: 'user', + ip: 'ip', +}); + +module.exports = ParseServer; diff --git a/src/cloud-code/httpRequest.js b/src/cloud-code/httpRequest.js deleted file mode 100644 index 0f70a8d6a6..0000000000 --- a/src/cloud-code/httpRequest.js +++ /dev/null @@ -1,158 +0,0 @@ -import HTTPResponse from './HTTPResponse'; -import querystring from 'querystring'; -import log from '../logger'; -import { http, https } from 'follow-redirects'; -import { parse } from 'url'; - -const clients = { - 'http:': http, - 'https:': https, -}; - -function makeCallback(resolve, reject) { - return function (response) { - const chunks = []; - response.on('data', chunk => { - chunks.push(chunk); - }); - response.on('end', () => { - const body = Buffer.concat(chunks); - const httpResponse = new HTTPResponse(response, body); - - // Consider <200 && >= 400 as errors - if (httpResponse.status < 200 || httpResponse.status >= 400) { - return reject(httpResponse); - } else { - return resolve(httpResponse); - } - }); - response.on('error', reject); - }; -} - -const encodeBody = function ({ body, headers = {} }) { - if (typeof body !== 'object') { - return { body, headers }; - } - var contentTypeKeys = Object.keys(headers).filter(key => { - return key.match(/content-type/i) != null; - }); - - if (contentTypeKeys.length == 0) { - // no content type - // As per https://parse.com/docs/cloudcode/guide#cloud-code-advanced-sending-a-post-request the default encoding is supposedly x-www-form-urlencoded - - body = querystring.stringify(body); - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } else { - /* istanbul ignore next */ - if (contentTypeKeys.length > 1) { - log.error('Parse.Cloud.httpRequest', 'multiple content-type headers are set.'); - } - // There maybe many, we'll just take the 1st one - var contentType = contentTypeKeys[0]; - if (headers[contentType].match(/application\/json/i)) { - body = JSON.stringify(body); - } else if (headers[contentType].match(/application\/x-www-form-urlencoded/i)) { - body = querystring.stringify(body); - } - } - return { body, headers }; -}; - -/** - * Makes an HTTP Request. - * - * **Available in Cloud Code only.** - * - * By default, Parse.Cloud.httpRequest does not follow redirects caused by HTTP 3xx response codes. You can use the followRedirects option in the {@link Parse.Cloud.HTTPOptions} object to change this behavior. - * - * Sample request: - * ``` - * Parse.Cloud.httpRequest({ - * url: 'http://www.parse.com/' - * }).then(function(httpResponse) { - * // success - * console.log(httpResponse.text); - * },function(httpResponse) { - * // error - * console.error('Request failed with response code ' + httpResponse.status); - * }); - * ``` - * - * @method httpRequest - * @name Parse.Cloud.httpRequest - * @param {Parse.Cloud.HTTPOptions} options The Parse.Cloud.HTTPOptions object that makes the request. - * @return {Promise} A promise that will be resolved with a {@link Parse.Cloud.HTTPResponse} object when the request completes. - */ -module.exports = function httpRequest(options) { - let url; - try { - url = parse(options.url); - } catch (e) { - return Promise.reject(e); - } - options = Object.assign(options, encodeBody(options)); - // support params options - if (typeof options.params === 'object') { - options.qs = options.params; - } else if (typeof options.params === 'string') { - options.qs = querystring.parse(options.params); - } - const client = clients[url.protocol]; - if (!client) { - return Promise.reject(`Unsupported protocol ${url.protocol}`); - } - const requestOptions = { - method: options.method, - port: Number(url.port), - path: url.pathname, - hostname: url.hostname, - headers: options.headers, - encoding: null, - followRedirects: options.followRedirects === true, - }; - if (requestOptions.headers) { - Object.keys(requestOptions.headers).forEach(key => { - if (typeof requestOptions.headers[key] === 'undefined') { - delete requestOptions.headers[key]; - } - }); - } - if (url.search) { - options.qs = Object.assign({}, options.qs, querystring.parse(url.query)); - } - if (url.auth) { - requestOptions.auth = url.auth; - } - if (options.qs) { - requestOptions.path += `?${querystring.stringify(options.qs)}`; - } - if (options.agent) { - requestOptions.agent = options.agent; - } - return new Promise((resolve, reject) => { - const req = client.request(requestOptions, makeCallback(resolve, reject, options)); - if (options.body) { - req.write(options.body); - } - req.on('error', error => { - reject(error); - }); - req.end(); - }); -}; - -/** - * @typedef Parse.Cloud.HTTPOptions - * @property {String|Object} body The body of the request. If it is a JSON object, then the Content-Type set in the headers must be application/x-www-form-urlencoded or application/json. You can also set this to a {@link Buffer} object to send raw bytes. If you use a Buffer, you should also set the Content-Type header explicitly to describe what these bytes represent. - * @property {function} error The function that is called when the request fails. It will be passed a Parse.Cloud.HTTPResponse object. - * @property {Boolean} followRedirects Whether to follow redirects caused by HTTP 3xx responses. Defaults to false. - * @property {Object} headers The headers for the request. - * @property {String} method The method of the request. GET, POST, PUT, DELETE, HEAD, and OPTIONS are supported. Will default to GET if not specified. - * @property {String|Object} params The query portion of the url. You can pass a JSON object of key value pairs like params: {q : 'Sean Plott'} or a raw string like params:q=Sean Plott. - * @property {function} success The function that is called when the request successfully completes. It will be passed a Parse.Cloud.HTTPResponse object. - * @property {string} url The url to send the request to. - */ - -module.exports.encodeBody = encodeBody; diff --git a/src/index.js b/src/index.js index bbbdaf545f..0c9069d6b5 100644 --- a/src/index.js +++ b/src/index.js @@ -6,7 +6,7 @@ import RedisCacheAdapter from './Adapters/Cache/RedisCacheAdapter'; import LRUCacheAdapter from './Adapters/Cache/LRUCache.js'; import * as TestUtils from './TestUtils'; import * as SchemaMigrations from './SchemaMigrations/Migrations'; - +import AuthAdapter from './Adapters/Auth/AuthAdapter'; import { useExternal } from './deprecated'; import { getLogger } from './logger'; import { PushWorker } from './Push/PushWorker'; @@ -16,11 +16,11 @@ import { ParseGraphQLServer } from './GraphQL/ParseGraphQLServer'; // Factory function const _ParseServer = function (options: ParseServerOptions) { const server = new ParseServer(options); - return server.app; + return server; }; // Mount the create liveQueryServer _ParseServer.createLiveQueryServer = ParseServer.createLiveQueryServer; -_ParseServer.start = ParseServer.start; +_ParseServer.startApp = ParseServer.startApp; const S3Adapter = useExternal('S3Adapter', '@parse/s3-files-adapter'); const GCSAdapter = useExternal('GCSAdapter', '@parse/gcs-files-adapter'); @@ -43,4 +43,5 @@ export { ParseGraphQLServer, _ParseServer as ParseServer, SchemaMigrations, + AuthAdapter, }; diff --git a/src/middlewares.js b/src/middlewares.js index 37acf46821..880315253f 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -7,6 +7,12 @@ import defaultLogger from './logger'; import rest from './rest'; import MongoStorageAdapter from './Adapters/Storage/Mongo/MongoStorageAdapter'; import PostgresStorageAdapter from './Adapters/Storage/Postgres/PostgresStorageAdapter'; +import rateLimit from 'express-rate-limit'; +import { RateLimitOptions } from './Options/Definitions'; +import { pathToRegexp } from 'path-to-regexp'; +import RedisStore from 'rate-limit-redis'; +import { createClient } from 'redis'; +import { BlockList, isIPv4 } from 'net'; export const DEFAULT_ALLOWED_HEADERS = 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control'; @@ -17,6 +23,46 @@ const getMountForRequest = function (req) { return req.protocol + '://' + req.get('host') + mountPath; }; +const getBlockList = (ipRangeList, store) => { + if (store.get('blockList')) return store.get('blockList'); + const blockList = new BlockList(); + ipRangeList.forEach(fullIp => { + if (fullIp === '::/0' || fullIp === '::') { + store.set('allowAllIpv6', true); + return; + } + if (fullIp === '0.0.0.0/0' || fullIp === '0.0.0.0') { + store.set('allowAllIpv4', true); + return; + } + const [ip, mask] = fullIp.split('/'); + if (!mask) { + blockList.addAddress(ip, isIPv4(ip) ? 'ipv4' : 'ipv6'); + } else { + blockList.addSubnet(ip, Number(mask), isIPv4(ip) ? 'ipv4' : 'ipv6'); + } + }); + store.set('blockList', blockList); + return blockList; +}; + +export const checkIp = (ip, ipRangeList, store) => { + const incomingIpIsV4 = isIPv4(ip); + const blockList = getBlockList(ipRangeList, store); + + if (store.get(ip)) return true; + if (store.get('allowAllIpv4') && incomingIpIsV4) return true; + if (store.get('allowAllIpv6') && !incomingIpIsV4) return true; + const result = blockList.check(ip, incomingIpIsV4 ? 'ipv4' : 'ipv6'); + + // If the ip is in the list, we store the result in the store + // so we have a optimized path for the next request + if (ipRangeList.includes(ip) && result) { + store.set(ip, result); + } + return result; +}; + // Checks that the request is authorized for this app and checks user // auth too. // The bodyparser should run before this middleware. @@ -41,6 +87,7 @@ export function handleParseHeaders(req, res, next) { appId: req.get('X-Parse-Application-Id'), sessionToken: req.get('X-Parse-Session-Token'), masterKey: req.get('X-Parse-Master-Key'), + maintenanceKey: req.get('X-Parse-Maintenance-Key'), installationId: req.get('X-Parse-Installation-Id'), clientKey: req.get('X-Parse-Client-Key'), javascriptKey: req.get('X-Parse-Javascript-Key'), @@ -157,23 +204,53 @@ export function handleParseHeaders(req, res, next) { } const clientIp = getClientIp(req); + const config = Config.get(info.appId, mount); + if (config.state && config.state !== 'ok') { + res.status(500); + res.json({ + code: Parse.Error.INTERNAL_SERVER_ERROR, + error: `Invalid server state: ${config.state}`, + }); + return; + } info.app = AppCache.get(info.appId); - req.config = Config.get(info.appId, mount); + req.config = config; req.config.headers = req.headers || {}; req.config.ip = clientIp; req.info = info; - if ( - info.masterKey && - req.config.masterKeyIps && - req.config.masterKeyIps.length !== 0 && - req.config.masterKeyIps.indexOf(clientIp) === -1 - ) { - return invalidRequest(req, res); + const isMaintenance = + req.config.maintenanceKey && info.maintenanceKey === req.config.maintenanceKey; + if (isMaintenance) { + if (checkIp(clientIp, req.config.maintenanceKeyIps || [], req.config.maintenanceKeyIpsStore)) { + req.auth = new auth.Auth({ + config: req.config, + installationId: info.installationId, + isMaintenance: true, + }); + next(); + return; + } + const log = req.config?.loggerController || defaultLogger; + log.error( + `Request using maintenance key rejected as the request IP address '${clientIp}' is not set in Parse Server option 'maintenanceKeyIps'.` + ); } - var isMaster = info.masterKey === req.config.masterKey; + let isMaster = info.masterKey === req.config.masterKey; + + if (isMaster && !checkIp(clientIp, req.config.masterKeyIps || [], req.config.masterKeyIpsStore)) { + const log = req.config?.loggerController || defaultLogger; + log.error( + `Request using master key rejected as the request IP address '${clientIp}' is not set in Parse Server option 'masterKeyIps'.` + ); + isMaster = false; + const error = new Error(); + error.status = 403; + error.message = `unauthorized`; + throw error; + } if (isMaster) { req.auth = new auth.Auth({ @@ -181,8 +258,7 @@ export function handleParseHeaders(req, res, next) { installationId: info.installationId, isMaster: true, }); - next(); - return; + return handleRateLimit(req, res, next); } var isReadOnlyMaster = info.masterKey === req.config.readOnlyMasterKey; @@ -197,8 +273,7 @@ export function handleParseHeaders(req, res, next) { isMaster: true, isReadOnly: true, }); - next(); - return; + return handleRateLimit(req, res, next); } // Client keys are not required in parse-server, but if any have been configured in the server, validate them @@ -226,8 +301,7 @@ export function handleParseHeaders(req, res, next) { isMaster: false, user: req.userFromJWT, }); - next(); - return; + return handleRateLimit(req, res, next); } if (!info.sessionToken) { @@ -236,66 +310,79 @@ export function handleParseHeaders(req, res, next) { installationId: info.installationId, isMaster: false, }); - next(); + } + handleRateLimit(req, res, next); +} + +const handleRateLimit = async (req, res, next) => { + const rateLimits = req.config.rateLimits || []; + try { + await Promise.all( + rateLimits.map(async limit => { + const pathExp = new RegExp(limit.path); + if (pathExp.test(req.url)) { + await limit.handler(req, res, err => { + if (err) { + if (err.code === Parse.Error.CONNECTION_FAILED) { + throw err; + } + req.config.loggerController.error( + 'An unknown error occured when attempting to apply the rate limiter: ', + err + ); + } + }); + } + }) + ); + } catch (error) { + res.status(429); + res.json({ code: Parse.Error.CONNECTION_FAILED, error: error.message }); return; } + next(); +}; - return Promise.resolve() - .then(() => { - // handle the upgradeToRevocableSession path on it's own - if ( - info.sessionToken && - req.url === '/upgradeToRevocableSession' && - info.sessionToken.indexOf('r:') != 0 - ) { - return auth.getAuthForLegacySessionToken({ - config: req.config, - installationId: info.installationId, - sessionToken: info.sessionToken, - }); - } else { - return auth.getAuthForSessionToken({ - config: req.config, - installationId: info.installationId, - sessionToken: info.sessionToken, - }); - } - }) - .then(auth => { - if (auth) { - req.auth = auth; - next(); - } - }) - .catch(error => { - if (error instanceof Parse.Error) { - next(error); - return; - } else { - // TODO: Determine the correct error scenario. - req.config.loggerController.error('error getting auth for sessionToken', error); - throw new Parse.Error(Parse.Error.UNKNOWN_ERROR, error); - } - }); -} +export const handleParseSession = async (req, res, next) => { + try { + const info = req.info; + if (req.auth || req.url === '/sessions/me') { + next(); + return; + } + let requestAuth = null; + if ( + info.sessionToken && + req.url === '/upgradeToRevocableSession' && + info.sessionToken.indexOf('r:') != 0 + ) { + requestAuth = await auth.getAuthForLegacySessionToken({ + config: req.config, + installationId: info.installationId, + sessionToken: info.sessionToken, + }); + } else { + requestAuth = await auth.getAuthForSessionToken({ + config: req.config, + installationId: info.installationId, + sessionToken: info.sessionToken, + }); + } + req.auth = requestAuth; + next(); + } catch (error) { + if (error instanceof Parse.Error) { + next(error); + return; + } + // TODO: Determine the correct error scenario. + req.config.loggerController.error('error getting auth for sessionToken', error); + throw new Parse.Error(Parse.Error.UNKNOWN_ERROR, error); + } +}; function getClientIp(req) { - if (req.headers['x-forwarded-for']) { - // try to get from x-forwared-for if it set (behind reverse proxy) - return req.headers['x-forwarded-for'].split(',')[0]; - } else if (req.connection && req.connection.remoteAddress) { - // no proxy, try getting from connection.remoteAddress - return req.connection.remoteAddress; - } else if (req.socket) { - // try to get it from req.socket - return req.socket.remoteAddress; - } else if (req.connection && req.connection.socket) { - // try to get it form the connection.socket - return req.connection.socket.remoteAddress; - } else { - // if non above, fallback. - return req.ip; - } + return req.ip; } function httpAuth(req) { @@ -342,8 +429,13 @@ export function allowCrossDomain(appId) { if (config && config.allowHeaders) { allowHeaders += `, ${config.allowHeaders.join(', ')}`; } - const allowOrigin = (config && config.allowOrigin) || '*'; - res.header('Access-Control-Allow-Origin', allowOrigin); + + const baseOrigins = + typeof config?.allowOrigin === 'string' ? [config.allowOrigin] : config?.allowOrigin ?? ['*']; + const requestOrigin = req.headers.origin; + const allowOrigins = + requestOrigin && baseOrigins.includes(requestOrigin) ? requestOrigin : baseOrigins[0]; + res.header('Access-Control-Allow-Origin', allowOrigins); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); res.header('Access-Control-Allow-Headers', allowHeaders); res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id'); @@ -424,6 +516,109 @@ export function promiseEnforceMasterKeyAccess(request) { return Promise.resolve(); } +export const addRateLimit = (route, config, cloud) => { + if (typeof config === 'string') { + config = Config.get(config); + } + for (const key in route) { + if (!RateLimitOptions[key]) { + throw `Invalid rate limit option "${key}"`; + } + } + if (!config.rateLimits) { + config.rateLimits = []; + } + const redisStore = { + connectionPromise: Promise.resolve(), + store: null, + connected: false, + }; + if (route.redisUrl) { + const client = createClient({ + url: route.redisUrl, + }); + redisStore.connectionPromise = async () => { + if (redisStore.connected) { + return; + } + try { + await client.connect(); + redisStore.connected = true; + } catch (e) { + const log = config?.loggerController || defaultLogger; + log.error(`Could not connect to redisURL in rate limit: ${e}`); + } + }; + redisStore.connectionPromise(); + redisStore.store = new RedisStore({ + sendCommand: async (...args) => { + await redisStore.connectionPromise(); + return client.sendCommand(args); + }, + }); + } + let transformPath = route.requestPath.split('/*').join('/(.*)'); + if (transformPath === '*') { + transformPath = '(.*)'; + } + config.rateLimits.push({ + path: pathToRegexp(transformPath), + handler: rateLimit({ + windowMs: route.requestTimeWindow, + max: route.requestCount, + message: route.errorResponseMessage || RateLimitOptions.errorResponseMessage.default, + handler: (request, response, next, options) => { + throw { + code: Parse.Error.CONNECTION_FAILED, + message: options.message, + }; + }, + skip: request => { + if (request.ip === '127.0.0.1' && !route.includeInternalRequests) { + return true; + } + if (route.includeMasterKey) { + return false; + } + if (route.requestMethods) { + if (Array.isArray(route.requestMethods)) { + if (!route.requestMethods.includes(request.method)) { + return true; + } + } else { + const regExp = new RegExp(route.requestMethods); + if (!regExp.test(request.method)) { + return true; + } + } + } + return request.auth?.isMaster; + }, + keyGenerator: async request => { + if (route.zone === Parse.Server.RateLimitZone.global) { + return request.config.appId; + } + const token = request.info.sessionToken; + if (route.zone === Parse.Server.RateLimitZone.session && token) { + return token; + } + if (route.zone === Parse.Server.RateLimitZone.user && token) { + if (!request.auth) { + await new Promise(resolve => handleParseSession(request, null, resolve)); + } + if (request.auth?.user?.id && request.zone === 'user') { + return request.auth.user.id; + } + } + return request.config.ip; + }, + store: redisStore.store, + }), + cloud, + }); + Config.put(config); +}; + /** * Deduplicates a request to ensure idempotency. Duplicates are determined by the request ID * in the request header. If a request has no request ID, it is executed anyway. diff --git a/src/request.js b/src/request.js index 2f85c3c9cf..bc58ee40ac 100644 --- a/src/request.js +++ b/src/request.js @@ -1 +1,174 @@ -module.exports = require('./cloud-code/httpRequest'); +import querystring from 'querystring'; +import log from './logger'; +import { http, https } from 'follow-redirects'; +import { parse } from 'url'; + +class HTTPResponse { + constructor(response, body) { + let _text, _data; + this.status = response.statusCode; + this.headers = response.headers || {}; + this.cookies = this.headers['set-cookie']; + + if (typeof body == 'string') { + _text = body; + } else if (Buffer.isBuffer(body)) { + this.buffer = body; + } else if (typeof body == 'object') { + _data = body; + } + + const getText = () => { + if (!_text && this.buffer) { + _text = this.buffer.toString('utf-8'); + } else if (!_text && _data) { + _text = JSON.stringify(_data); + } + return _text; + }; + + const getData = () => { + if (!_data) { + try { + _data = JSON.parse(getText()); + } catch (e) { + /* */ + } + } + return _data; + }; + + Object.defineProperty(this, 'body', { + get: () => { + return body; + }, + }); + + Object.defineProperty(this, 'text', { + enumerable: true, + get: getText, + }); + + Object.defineProperty(this, 'data', { + enumerable: true, + get: getData, + }); + } +} + +const clients = { + 'http:': http, + 'https:': https, +}; + +function makeCallback(resolve, reject) { + return function (response) { + const chunks = []; + response.on('data', chunk => { + chunks.push(chunk); + }); + response.on('end', () => { + const body = Buffer.concat(chunks); + const httpResponse = new HTTPResponse(response, body); + + // Consider <200 && >= 400 as errors + if (httpResponse.status < 200 || httpResponse.status >= 400) { + return reject(httpResponse); + } else { + return resolve(httpResponse); + } + }); + response.on('error', reject); + }; +} + +const encodeBody = function ({ body, headers = {} }) { + if (typeof body !== 'object') { + return { body, headers }; + } + var contentTypeKeys = Object.keys(headers).filter(key => { + return key.match(/content-type/i) != null; + }); + + if (contentTypeKeys.length == 0) { + // no content type + // As per https://parse.com/docs/cloudcode/guide#cloud-code-advanced-sending-a-post-request the default encoding is supposedly x-www-form-urlencoded + + body = querystring.stringify(body); + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } else { + /* istanbul ignore next */ + if (contentTypeKeys.length > 1) { + log.error('Parse.Cloud.httpRequest', 'multiple content-type headers are set.'); + } + // There maybe many, we'll just take the 1st one + var contentType = contentTypeKeys[0]; + if (headers[contentType].match(/application\/json/i)) { + body = JSON.stringify(body); + } else if (headers[contentType].match(/application\/x-www-form-urlencoded/i)) { + body = querystring.stringify(body); + } + } + return { body, headers }; +}; + +function httpRequest(options) { + let url; + try { + url = parse(options.url); + } catch (e) { + return Promise.reject(e); + } + options = Object.assign(options, encodeBody(options)); + // support params options + if (typeof options.params === 'object') { + options.qs = options.params; + } else if (typeof options.params === 'string') { + options.qs = querystring.parse(options.params); + } + const client = clients[url.protocol]; + if (!client) { + return Promise.reject(`Unsupported protocol ${url.protocol}`); + } + const requestOptions = { + method: options.method, + port: Number(url.port), + path: url.pathname, + hostname: url.hostname, + headers: options.headers, + encoding: null, + followRedirects: options.followRedirects === true, + }; + if (requestOptions.headers) { + Object.keys(requestOptions.headers).forEach(key => { + if (typeof requestOptions.headers[key] === 'undefined') { + delete requestOptions.headers[key]; + } + }); + } + if (url.search) { + options.qs = Object.assign({}, options.qs, querystring.parse(url.query)); + } + if (url.auth) { + requestOptions.auth = url.auth; + } + if (options.qs) { + requestOptions.path += `?${querystring.stringify(options.qs)}`; + } + if (options.agent) { + requestOptions.agent = options.agent; + } + return new Promise((resolve, reject) => { + const req = client.request(requestOptions, makeCallback(resolve, reject, options)); + if (options.body) { + req.write(options.body); + } + req.on('error', error => { + reject(error); + }); + req.end(); + }); +} +module.exports = httpRequest; +module.exports.encodeBody = encodeBody; +module.exports.HTTPResponse = HTTPResponse; diff --git a/src/rest.js b/src/rest.js index fca3497a5d..1f9dbacb73 100644 --- a/src/rest.js +++ b/src/rest.js @@ -12,6 +12,7 @@ var Parse = require('parse/node').Parse; var RestQuery = require('./RestQuery'); var RestWrite = require('./RestWrite'); var triggers = require('./triggers'); +const { enforceRoleSecurity } = require('./SharedRest'); function checkTriggers(className, config, types) { return types.some(triggerType => { @@ -24,65 +25,34 @@ function checkLiveQuery(className, config) { } // Returns a promise for an object with optional keys 'results' and 'count'. -function find(config, auth, className, restWhere, restOptions, clientSDK, context) { - enforceRoleSecurity('find', className, auth); - return triggers - .maybeRunQueryTrigger( - triggers.Types.beforeFind, - className, - restWhere, - restOptions, - config, - auth, - context - ) - .then(result => { - restWhere = result.restWhere || restWhere; - restOptions = result.restOptions || restOptions; - const query = new RestQuery( - config, - auth, - className, - restWhere, - restOptions, - clientSDK, - true, - context - ); - return query.execute(); - }); -} +const find = async (config, auth, className, restWhere, restOptions, clientSDK, context) => { + const query = await RestQuery({ + method: RestQuery.Method.find, + config, + auth, + className, + restWhere, + restOptions, + clientSDK, + context, + }); + return query.execute(); +}; // get is just like find but only queries an objectId. -const get = (config, auth, className, objectId, restOptions, clientSDK, context) => { +const get = async (config, auth, className, objectId, restOptions, clientSDK, context) => { var restWhere = { objectId }; - enforceRoleSecurity('get', className, auth); - return triggers - .maybeRunQueryTrigger( - triggers.Types.beforeFind, - className, - restWhere, - restOptions, - config, - auth, - context, - true - ) - .then(result => { - restWhere = result.restWhere || restWhere; - restOptions = result.restOptions || restOptions; - const query = new RestQuery( - config, - auth, - className, - restWhere, - restOptions, - clientSDK, - true, - context - ); - return query.execute(); - }); + const query = await RestQuery({ + method: RestQuery.Method.get, + config, + auth, + className, + restWhere, + restOptions, + clientSDK, + context, + }); + return query.execute(); }; // Returns a promise that doesn't resolve to any useful value. @@ -101,40 +71,45 @@ function del(config, auth, className, objectId, context) { let schemaController; return Promise.resolve() - .then(() => { + .then(async () => { const hasTriggers = checkTriggers(className, config, ['beforeDelete', 'afterDelete']); const hasLiveQuery = checkLiveQuery(className, config); if (hasTriggers || hasLiveQuery || className == '_Session') { - return new RestQuery(config, auth, className, { objectId }) - .execute({ op: 'delete' }) - .then(response => { - if (response && response.results && response.results.length) { - const firstResult = response.results[0]; - firstResult.className = className; - if (className === '_Session' && !auth.isMaster) { - if (!auth.user || firstResult.user.objectId !== auth.user.id) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } + const query = await RestQuery({ + method: RestQuery.Method.get, + config, + auth, + className, + restWhere: { objectId }, + }); + return query.execute({ op: 'delete' }).then(response => { + if (response && response.results && response.results.length) { + const firstResult = response.results[0]; + firstResult.className = className; + if (className === '_Session' && !auth.isMaster && !auth.isMaintenance) { + if (!auth.user || firstResult.user.objectId !== auth.user.id) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); } - var cacheAdapter = config.cacheController; - cacheAdapter.user.del(firstResult.sessionToken); - inflatedObject = Parse.Object.fromJSON(firstResult); - return triggers.maybeRunTrigger( - triggers.Types.beforeDelete, - auth, - inflatedObject, - null, - config, - context - ); } - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for delete.'); - }); + var cacheAdapter = config.cacheController; + cacheAdapter.user.del(firstResult.sessionToken); + inflatedObject = Parse.Object.fromJSON(firstResult); + return triggers.maybeRunTrigger( + triggers.Types.beforeDelete, + auth, + inflatedObject, + null, + config, + context + ); + } + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for delete.'); + }); } return Promise.resolve({}); }) .then(() => { - if (!auth.isMaster) { + if (!auth.isMaster && !auth.isMaintenance) { return auth.getUserRoles(); } else { return; @@ -144,7 +119,7 @@ function del(config, auth, className, objectId, context) { .then(s => { schemaController = s; const options = {}; - if (!auth.isMaster) { + if (!auth.isMaster && !auth.isMaintenance) { options.acl = ['*']; if (auth.user) { options.acl.push(auth.user.id); @@ -193,21 +168,22 @@ function update(config, auth, className, restWhere, restObject, clientSDK, conte enforceRoleSecurity('update', className, auth); return Promise.resolve() - .then(() => { + .then(async () => { const hasTriggers = checkTriggers(className, config, ['beforeSave', 'afterSave']); const hasLiveQuery = checkLiveQuery(className, config); if (hasTriggers || hasLiveQuery) { // Do not use find, as it runs the before finds - return new RestQuery( + const query = await RestQuery({ + method: RestQuery.Method.get, config, auth, className, restWhere, - undefined, - undefined, - false, - context - ).execute({ + runAfterFind: false, + runBeforeFind: false, + context, + }); + return query.execute({ op: 'update', }); } @@ -237,42 +213,17 @@ function update(config, auth, className, restWhere, restObject, clientSDK, conte function handleSessionMissingError(error, className, auth) { // If we're trying to update a user without / with bad session token - if (className === '_User' && error.code === Parse.Error.OBJECT_NOT_FOUND && !auth.isMaster) { + if ( + className === '_User' && + error.code === Parse.Error.OBJECT_NOT_FOUND && + !auth.isMaster && + !auth.isMaintenance + ) { throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth.'); } throw error; } -const classesWithMasterOnlyAccess = [ - '_JobStatus', - '_PushStatus', - '_Hooks', - '_GlobalConfig', - '_JobSchedule', - '_Idempotency', -]; -// Disallowing access to the _Role collection except by master key -function enforceRoleSecurity(method, className, auth) { - if (className === '_Installation' && !auth.isMaster) { - if (method === 'delete' || method === 'find') { - const error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } - } - - //all volatileClasses are masterKey only - if (classesWithMasterOnlyAccess.indexOf(className) >= 0 && !auth.isMaster) { - const error = `Clients aren't allowed to perform the ${method} operation on the ${className} collection.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } - - // readOnly masterKey is not allowed - if (auth.isReadOnly && (method === 'delete' || method === 'create' || method === 'update')) { - const error = `read-only masterKey isn't allowed to perform the ${method} operation.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } -} - module.exports = { create, del, diff --git a/src/triggers.js b/src/triggers.js index 4ba21b32ea..34ace35b4b 100644 --- a/src/triggers.js +++ b/src/triggers.js @@ -86,6 +86,12 @@ const Category = { }; function getStore(category, name, applicationId) { + const invalidNameRegex = /['"`]/; + if (invalidNameRegex.test(name)) { + // Prevent a malicious user from injecting properties into the store + return {}; + } + const path = name.split('.'); path.splice(-1); // remove last component applicationId = applicationId || Parse.applicationId; @@ -94,7 +100,7 @@ function getStore(category, name, applicationId) { for (const component of path) { store = store[component]; if (!store) { - return undefined; + return {}; } } return store; @@ -270,6 +276,8 @@ export function getRequestObject( triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete || + triggerType === Types.beforeLogin || + triggerType === Types.afterLogin || triggerType === Types.afterFind ) { // Set a copy of the context on the request object. @@ -373,9 +381,9 @@ function userIdForLog(auth) { return auth && auth.user ? auth.user.id : undefined; } -function logTriggerAfterHook(triggerType, className, input, auth) { +function logTriggerAfterHook(triggerType, className, input, auth, logLevel) { const cleanInput = logger.truncateLogMessage(JSON.stringify(input)); - logger.info( + logger[logLevel]( `${triggerType} triggered for ${className} for user ${userIdForLog( auth )}:\n Input: ${cleanInput}`, @@ -387,10 +395,10 @@ function logTriggerAfterHook(triggerType, className, input, auth) { ); } -function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) { +function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth, logLevel) { const cleanInput = logger.truncateLogMessage(JSON.stringify(input)); const cleanResult = logger.truncateLogMessage(JSON.stringify(result)); - logger.info( + logger[logLevel]( `${triggerType} triggered for ${className} for user ${userIdForLog( auth )}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, @@ -402,9 +410,9 @@ function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth ); } -function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) { +function logTriggerErrorBeforeHook(triggerType, className, input, auth, error, logLevel) { const cleanInput = logger.truncateLogMessage(JSON.stringify(input)); - logger.error( + logger[logLevel]( `${triggerType} failed for ${className} for user ${userIdForLog( auth )}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, @@ -444,7 +452,14 @@ export function maybeRunAfterFindTrigger( reject(error); } ); - logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth); + logTriggerSuccessBeforeHook( + triggerType, + className, + 'AfterFind', + JSON.stringify(objects), + auth, + config.logLevels.triggerBeforeSuccess + ); request.objects = objects.map(object => { //setting the class name to transform into parse object object.className = className; @@ -468,7 +483,13 @@ export function maybeRunAfterFindTrigger( }) .then(success, error); }).then(results => { - logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth); + logTriggerAfterHook( + triggerType, + className, + JSON.stringify(results), + auth, + config.logLevels.triggerAfter + ); return results; }); } @@ -561,6 +582,10 @@ export function maybeRunQueryTrigger( restOptions = restOptions || {}; restOptions.hint = jsonQuery.hint; } + if (jsonQuery.comment) { + restOptions = restOptions || {}; + restOptions.comment = jsonQuery.comment; + } if (requestObject.readPreference) { restOptions = restOptions || {}; restOptions.readPreference = requestObject.readPreference; @@ -842,7 +867,10 @@ export function maybeRunTrigger( parseObject.className, parseObject.toJSON(), object, - auth + auth, + triggerType.startsWith('after') + ? config.logLevels.triggerAfter + : config.logLevels.triggerBeforeSuccess ); if ( triggerType === Types.beforeSave || @@ -860,7 +888,8 @@ export function maybeRunTrigger( parseObject.className, parseObject.toJSON(), auth, - error + error, + config.logLevels.triggerBeforeError ); reject(error); } @@ -885,7 +914,13 @@ export function maybeRunTrigger( triggerType === Types.afterDelete || triggerType === Types.afterLogin ) { - logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth); + logTriggerAfterHook( + triggerType, + parseObject.className, + parseObject.toJSON(), + auth, + config.logLevels.triggerAfter + ); } // beforeSave is expected to return null (nothing) if (triggerType === Types.beforeSave) { @@ -965,7 +1000,8 @@ export async function maybeRunFileTrigger(triggerType, fileObject, config, auth) 'Parse.File', { ...fileObject.file.toJSON(), fileSize: fileObject.fileSize }, result, - auth + auth, + config.logLevels.triggerBeforeSuccess ); return result || fileObject; } catch (error) { @@ -974,7 +1010,8 @@ export async function maybeRunFileTrigger(triggerType, fileObject, config, auth) 'Parse.File', { ...fileObject.file.toJSON(), fileSize: fileObject.fileSize }, auth, - error + error, + config.logLevels.triggerBeforeError ); throw error; } diff --git a/src/vendor/mongodbUrl.js b/src/vendor/mongodbUrl.js index 7617293097..2aa422a9cd 100644 --- a/src/vendor/mongodbUrl.js +++ b/src/vendor/mongodbUrl.js @@ -1,8 +1,7 @@ -// A slightly patched version of node's url module, with support for mongodb:// -// uris. -// -// See https://github.com/nodejs/node/blob/master/LICENSE for licensing -// information +/* + * A slightly patched version of node's URL module, with support for `mongodb://` URIs. + * See https://github.com/nodejs/node for licensing information. + */ 'use strict';